0

我正在尝试计算 Ruby 中字符串的相似前缀开头的数量。例如; 输入“ababaa”应该输出11;

ababaa = 6
 babaa = 0
  abaa = 3
   baa = 0
    aa = 1
     a = 1

我已经了解了下面的代码,使用嵌套循环将上述每个作为数组进行遍历,但是看起来 Ruby 当前仅输出第一个 Array 对象“ababaa”的计数。

解决了,谢谢:)

def string_suffix(string)
num = 0
ary = []
string.length.times do
  ary << string[num..string.length]
  num = num + 1
end
result = 0
ary.each do |x| # ["ababaa", "babaa", "abaa", "baa", "aa", "a"] 
  x.chars.each_with_index do |c,index|
    break unless c == string[index]
      result = result + 1
  end
end
return result
end

我已经看得很远了,仍然无法解决这个问题,看起来(最终的,嵌套的)数组在“ary”数组的第一次迭代之后中断了,只是返回了那个输出。

4

3 回答 3

3

当您仍在循环中时,您正在返回结果。您需要移出result = 0循环,并将return result语句也移出循环。目前该函数正在执行循环的第一次迭代(“ababaa”,所有字符都匹配),但您希望结果等于所有结果的总和。

此外,不要这样做:

count = 0
x.chars.each do |x|
    if x == string[count]
        count = count + 1
        result = result + 1
    else
        count = count + 1
    end
end

您可以使用 each_with_index 函数来获取

x.chars.each_with_index do |c,index|
    if c == string[index]
        result = result + 1
    end
end

但是,由于您正在尝试计算子字符串中有多少个字符是字符串的前缀,因此您希望在第一次找到不等于 string[index] 的字符 c 时中断,这样您最终就不会计数额外的字符。然后循环变为:

x.chars.each_with_index do |c,index|
    if c == string[index]
        result = result + 1
    else
        break
    end
end
于 2015-08-27T18:34:09.133 回答
0

我注意到你最后在第二个循环中返回了结果。这意味着在您完成数组中的第一项之后,该函数仅返回第一项的结果。将您的 return 语句移到循环之外。

于 2015-08-27T18:37:30.093 回答
0

据我了解,问题是这样的:给定一个字符串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设置为1tot,我们刚刚计算的,等于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

于 2015-08-30T23:14:34.937 回答