例如我有一個數組如何在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)僅當它們出現在序列中的兩個或更多次。
例如我有一個數組如何在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)僅當它們出現在序列中的兩個或更多次。
實施塞爾吉奧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] }
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
,除非它已經是一個數組。
對不起,在第一個地方,我沒有包括你的一個基準報告...謝謝你加入.. * + 1 *也給你.. :)) –
不要對不起!我自己添加時沒有問題;) – tessi
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]
基準
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)
將我的實現添加到您的基準測試中,希望對您有用。 – tessi
@tessi我沒有問題..你可以添加它..請繼續.. :) –
這會工作,太:
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]]
正如你已經減少它,那麼爲什麼不'g.chunk {| e | e} .flat_map {| a,b |一個== 0 || b.length == 1? b:[b]}? :)) –
@Priti謝謝你的指針,我以爲'flat_map'會變平'[b]' – Stefan
* + 1 * ..'chunk'是處理這個問題的好方法..它會工作..我檢查了.. :)感覺嫉妒你..爲什麼我沒有想到的那部分.. :))):D –
所以,你在哪裏卡住了? –
只是不知道該怎麼做.. – DenisKo
好吧,這裏有一個想法:通過源數組循環並檢查元素。如果它不是'1',則將其附加到結果數組中。如果它是'1',則將其追加到臨時數組中。如果它不是'1',則將該臨時數組附加到結果數組。 –