据我了解,问题是这样的:给定一个字符串s
,对于每个,计算与 的相应字符(即,在相同的偏移量处)匹配的i = 0..s.size-1
前导字符数,并将这些小计相加。s[0..-i-1]
s[i..-1]
s.size
这是一种类似 Ruby 的方法,使用Enumerable#reduce (aka inject
) 和Enumerable#take_while:
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
。