Ruby 中的嵌套循环
Nested loops in Ruby
我正在尝试计算 Ruby 中字符串的相似前缀开头的数量。例如;输入 "ababaa" 应该输出 11;
ababaa = 6
babaa = 0
abaa = 3
baa = 0
aa = 1
a = 1
我已经得到了下面的代码,使用嵌套循环将上面的每一个都作为一个数组进行遍历,但是看起来 Ruby 目前正在输出第一个数组的计数对象,"ababaa".
Solved, thanks :)
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' 数组的第一次迭代后被打破,只是返回那个输出。
您仍在循环中时返回结果。您需要将 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
但是,由于您要计算子字符串中有多少个字符是字符串的前缀,因此您希望在第一次找到不等于字符串 [index] 的字符 c 时中断,这样您就不会' 最终计算额外的字符。然后循环变为:
x.chars.each_with_index do |c,index|
if c == string[index]
result = result + 1
else
break
end
end
我注意到您在第二个循环的最后 return 计算结果。这意味着在您完成数组中的第一项之后,函数 returns 只是第一项的结果。将您的 return 语句移到循环外。
据我了解,问题是这样的:给定一个字符串 s
,对于每个 i = 0..s.size-1
,计算 s[0..-i-1]
中与相应字符匹配的前导字符数(即,在相同的偏移量下)s[i..-1]
,并对这些 s.size
小计求和。
这是一个类似于 Ruby 的方法,使用 Enumerable#reduce (aka inject
) and 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
的第一个元素,此计算将始终等于 arr.size
。
当 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
returns tot
.
的值
我正在尝试计算 Ruby 中字符串的相似前缀开头的数量。例如;输入 "ababaa" 应该输出 11;
ababaa = 6
babaa = 0
abaa = 3
baa = 0
aa = 1
a = 1
我已经得到了下面的代码,使用嵌套循环将上面的每一个都作为一个数组进行遍历,但是看起来 Ruby 目前正在输出第一个数组的计数对象,"ababaa".
Solved, thanks :)
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' 数组的第一次迭代后被打破,只是返回那个输出。
您仍在循环中时返回结果。您需要将 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
但是,由于您要计算子字符串中有多少个字符是字符串的前缀,因此您希望在第一次找到不等于字符串 [index] 的字符 c 时中断,这样您就不会' 最终计算额外的字符。然后循环变为:
x.chars.each_with_index do |c,index|
if c == string[index]
result = result + 1
else
break
end
end
我注意到您在第二个循环的最后 return 计算结果。这意味着在您完成数组中的第一项之后,函数 returns 只是第一项的结果。将您的 return 语句移到循环外。
据我了解,问题是这样的:给定一个字符串 s
,对于每个 i = 0..s.size-1
,计算 s[0..-i-1]
中与相应字符匹配的前导字符数(即,在相同的偏移量下)s[i..-1]
,并对这些 s.size
小计求和。
这是一个类似于 Ruby 的方法,使用 Enumerable#reduce (aka inject
) and 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
的第一个元素,此计算将始终等于 arr.size
。
当 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
returns tot
.