[英]How can I improve the performance of this small Ruby function?
我目前正在執行 Ruby 質詢,並且對於某些字符串輸入很長(10.000+ 個字符)的測試用例, Terminated due to timeout
出現錯誤。
如何改進我的代碼?
給您一個僅包含字符 A 和 B 的字符串。 您的任務是將其更改為沒有匹配的相鄰字符的字符串。 為此,您可以刪除字符串中的零個或多個字符。
您的任務是找到所需刪除的最少數量。
例如,給定字符串s = AABAAB
,刪除位置0
和3
的A
以使s = ABAB
刪除2
。
def alternatingCharacters(s)
counter = 0
s.chars.each_with_index { |char, idx| counter += 1 if s.chars[idx + 1] == char }
return counter
end
謝謝!
這可能會更快地返回計數:
str.size - str.chars.chunk_while{ |a, b| a == b }.to_a.size
第二部分將String#chars方法與Enumerable#chunk_while結合使用。 這樣第二部分在子數組中分組:
'aababbabbaab'.chars.chunk_while{ |a, b| a == b}.to_a
#=> [["a", "a"], ["b"], ["a"], ["b", "b"], ["a"], ["b", "b"], ["a", "a"], ["b"]]
如果可以使用,則squeeze
:
str.length - str.squeeze.length
否則,您可以嘗試匹配前面有另一個A
(或B
)的那些A
(或B
)的正則表達式:
str.enum_for(:scan, /(?<=A)A|(?<=B)B/).count
使用enum_for
可以避免創建中間數組。
主要問題:
s.chars.each_with_index { |char, idx| counter += 1 if s.chars[idx + 1] == char }
是您不將chars
保存到變量中的事實。 s.chars
會將字符串撕成一個字符數組。 循環外的第一個s.chars
調用很好。 但是,沒有理由對s
中的每個字符都這樣做。 這意味着如果您有一個 10.000 個字符的字符串,您將實例化大小為 10.000 的 10.001 arrays。
重新使用字符數組會給你帶來巨大的性能提升:
require 'benchmark'
s = ''
options = %w[A B]
10_000.times { s << options.sample }
Benchmark.bm do |x|
x.report do
counter = 0
s.chars.each_with_index { |char, idx| counter += 1 if s.chars[idx + 1] == char }
# create a character array for each iteration ^
end
x.report do
counter = 0
chars = s.chars # <- only create a character array once
chars.each_with_index { |char, idx| counter += 1 if chars[idx + 1] == char }
end
end
user system total real
8.279767 0.000001 8.279768 ( 8.279655)
0.002188 0.000003 0.002191 ( 0.002191)
您還可以使用each_cons
和count
之類的枚舉器方法來簡化代碼,這不會大大增加性能成本,但會使代碼更具可讀性。
Benchmark.bm do |x|
x.report do
counter = 0
chars = s.chars
chars.each_with_index { |char, idx| counter += 1 if chars[idx + 1] == char }
end
x.report do
s.each_char.each_cons(2).count { |a, b| a == b }
# ^ using each_char instead of chars to avoid
# instantiating a character array
end
end
user system total real
0.002923 0.000000 0.002923 ( 0.002920)
0.003995 0.000000 0.003995 ( 0.003994)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.