2013-07-24 3 views
0

Например, у меня есть массивКак создать массивы внутри массива, если условие соответствия на Ruby?

g = [0,0,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1] 

И в результате мне нужно

f = [0,0,0,[1,1,1],0,[1,1],0,0,1,0,0,[1,1,1,1],0,0,0,[1,1,1]] 

нужно соединить элементы (1) только тогда, когда они появляются два или более раз в последовательности.

+0

Итак, где ты застрял? –

+0

Просто не знаю, как это сделать. – DenisKo

+0

Ну, вот идея: проведите через свой исходный массив и проверьте элементы. Если это не '1', добавьте его в массив результатов. Если это '1', добавьте его во временный массив. Если это еще не '1', добавьте этот массив temp в массив результатов. –

ответ

0

Реализована идея Серхио Tulentsev

g = [0,0,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1] 
f = [] 
ones = [] 
g.each { |x| 
    if x == 1 
    ones << x 
    else 
    if ones.size > 1 
     f << ones 
    elsif ones.size == 1 
     f += ones 
    end 
    ones = [] 
    f << x 
    end 
} 
if ones.size > 1 
    f << ones 
elsif ones.size == 1 
    f += ones 
end 

UPDATE

альтернативный

g = [0,0,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1] 
f = [] 
g.each { |x| 
    if x == 1 
    f << [] if ! f.last.is_a? Array 
    f.last << x 
    else 
    f << x 
    end 
} 
f.each_with_index { |x,i| f[i] = 1 if x == [1] } 
1
g.inject([]) do |ary, i| 
    if i == 0 or ary.last == 0 
    ary << i 
    else 
    ary[-1] = Array(ary.last) << i 
    ary 
    end 
end 

=> [0, 0, 0, [1, 1, 1], 0, [1, 1], 0, 0, 1, 0, 0, [1, 1, 1, 1], 0, 0, 0, [1, 1, 1]] 

Это должно быть в O (N) во время выполнения.

FYI: Array(thing) обертывает thing в массиве ([thing]), если он уже не является массивом.

+0

Извините, на первом месте я не включил ваш в тестовый отчет ... Спасибо, что добавил .. * + 1 * вам тоже .. :)) –

+0

Не пожалеете! У меня нет проблем с его добавлением;) – tessi

1

Enumerable#chunk будет отличным вариантом для этого.

g = [0,0,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1] 
p g.chunk{|i| i == 0}.to_a 
# >> [[true, [0, 0, 0]], [false, [1, 1, 1]], [true, [0]], 
# [false, [1, 1]], [true, [0, 0]], [false, [1]], 
# [true, [0, 0]], [false, [1, 1, 1, 1]], 
# [true, [0, 0, 0]], [false, [1, 1, 1]]] 
ar = g.chunk{|i| i == 0}.each_with_object([]) do |(e1,e2),a| 
    (!e1 && e2.size > 1) ? a.concat([e2]) : a.concat(e2) 
end 
p ar 
# >> [0, 0, 0, [1, 1, 1], 0, [1, 1], 0, 0, 1, 0, 0, 
# [1, 1, 1, 1], 0, 0, 0, [1, 1, 1] 

Benchmark

require 'benchmark' 

g = [0,0,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1] 
n = 1000000 
Benchmark.bm(15) do |x| 
    x.report('stefan') { n.times { g.chunk{ |e| e }.flat_map { |a, b| a == 0 || b.length == 1 ? b : [b] } } } 
    x.report('priti') { n.times { g.chunk{|i| i == 0}.each_with_object([]){|(e1,e2),a| (!e1 && e2.size > 1) ? a.concat([e2]) : a.concat(e2)} } } 
    x.report('tessi') { n.times { g.inject([]) { |ary, i| (i == 0 or ary.last == 0) ? ary << i : (ary[-1] = Array(ary.last) << i); ary }}} 
end 

         user  system  total  real 
stefan   11.860000 0.000000 11.860000 (11.890553) 
priti   13.360000 0.000000 13.360000 (13.406585) 
tessi    5.650000 0.000000 5.650000 ( 5.666377) 
+0

Добавил мою реализацию в свой тест, надеюсь, что все в порядке для вас. – tessi

+0

@tessi У меня нет проблем .. Вы можете добавить его .. пожалуйста, вперед .. :) –

3

Это будет работать, тоже:

g.chunk{ |e| e }.flat_map { |a, b| a == 0 || b.length == 1 ? b : [b] } 
#=> [0, 0, 0, [1, 1, 1], 0, [1, 1], 0, 0, 1, 0, 0, [1, 1, 1, 1], 0, 0, 0, [1, 1, 1]] 
+0

Как вы уже сократили его, так почему бы не 'g.chunk {| e | e} .flat_map {| a, b | a == 0 || b.length == 1? b: [b]} '? :)) –

+1

@Priti спасибо за указатель, я думал, что 'flat_map' будет сплющить' [b] ' – Stefan

+0

* + 1 * ..' chunk' хороший способ справиться с этим..Он будет работать .. я проверил .. :) чувство ревности к тебе .. почему я не думал до этой части .. :))): D –

Смежные вопросы