私が理解しているように、問題は次のとおりです。 string が与えられたs
場合、 の対応する文字 (つまり、同じオフセット) と一致するi = 0..s.size-1
の先頭文字の数を計算し、これらの小計を合計します。s[0..-i-1]
s[i..-1]
s.size
Enumerable#reduce (別名inject
) とEnumerable#take_whileを使用して、これを行う Ruby のような方法を次に示します。
str = "ababaa"
arr = str.chars
(0...arr.size).reduce(0) do |tot,i|
tot + arr[0..-i-1].zip(arr[i..-1]).take_while { |x,y| x == y }.size
end
#=> 11
手順:
arr = str.chars
#=> ["a", "b", "a", "b", "a", "a"]
r = 0...arr.size
#=> 0...6
の最初の要素がr
ブロックに渡されると、ブロック変数は次のように設定されます。
tot = 0
i = 0
したがって、ブロック計算は次のようになります。
a = arr[0..-i-1].zip(arr[i..-1])
#=> arr[0..-1].zip(arr[0..-1])
#=> arr.zip(arr)
#=> ["a", "b", "a", "b", "a", "a"].zip(["a", "b", "a", "b", "a", "a"])
#=> [["a", "a"], ["b", "b"], ["a", "a"], ["b", "b"], ["a", "a"], ["a", "a"]]
b = a.take_while { |x,y| x == y }
#=> [["a", "a"], ["b", "b"], ["a", "a"], ["b", "b"], ["a", "a"], ["a", "a"]]
tot + b.size
#=> 0 + 6
#=> 6
この計算は、ブロックに渡されるarr.size
最初の要素に対して常に等しいことに注意してください。arr
の次の要素がarr
ブロックに渡されると、ブロック変数i
が に設定され1
ます。tot
計算したばかりの は、 に等しくなり6
ます。したがって、ブロック計算は次のようになります。
a = arr[0..-i-1].zip(arr[i..-1])
#=> arr[0..-2].zip(arr[1..-1])
#=> ["a", "b", "a", "b", "a"].zip(["b", "a", "b", "a", "a"])
#=> [["a", "b"], ["b", "a"], ["a", "b"], ["b", "a"], ["a", "a"]]
b = a.take_while { |x,y| x == y }
#=> []
tot + b.size
#=> 6 + 0
#=> 6
残りの計算は同様です。のすべての要素がarr
ブロックに送信された後reduce
、 の値を返しますtot
。