理解 ruby 中的 'next' - 比较解决方案
Understanding 'next' in ruby - comparing solutions
我正在上在线课程:
Write a method that takes a string and returns true
if the letter "z"
appears within three letters after an "a"
. You may assume that the string contains only lowercase letters.
这是给出的解决方案:
def nearby_az(string)
i = 0
while i < string.length
if string[i] != "a"
i += 1
next
end
j = i + 1
while (j < string.length) && (j <= i + 3)
if string[j] == "z"
return true
end
j += 1
end
i += 1
end
return false
end
这个解决方案对我来说似乎过于复杂。具体来说,我不明白为什么需要 next
。我想知道是否有人可以帮助我理解这个功能。
我的解决方案似乎与我尝试过的测试一样有效,但我想知道其他解决方案是否更好,我的解决方案是否会出现我尚未遇到的问题。
def nearby_az(string)
i = 0
while i < string.length
while string[i] != "a"
i += 1
end
if string[i + 1] == "z" || string[i + 2] == "z" || string[i + 3] == "z"
return true
else
i += 1
end
return false
end
end
在原来的答案中,如果您删除 next
,i
索引将被假定代表一个 "a"
位置,即使它不是,并且将 return 一个错误的结果。
当你将一个像"b"
这样的字符串传递给你的代码时,它会进入一个无限循环,因为外部条件while i < string.length
无法控制:
while string[i] != "a"
i += 1
end
注意,一旦 i
超出字符串的最后位置,条件 string[i]
变为 nil
,并且 string[i] != "a"
将从那里得到满足。
如果字符串看起来像这样 "bbbbb..." 或像这样 "abb" - 即 -
1) 如果 string.length < 4 (no string[i+3]) 你的代码会崩溃
2) 如果字符串中没有 "a",您的代码将崩溃。
这里 "next" 派上用场了:
"next" 的目的是跳过循环的其余部分并直接跳回到它的开头。因此,最初的解决方案将首先遍历字符,直到找到 "a" (跳过循环的另一部分不是)并且当且仅当它找到 "a" - 它会找到 "z".
因此,如 sawa 所述,您的循环不接受其中没有 a 的字符串。它也不理解具有多个 a 的字符串。例如 aaaaaaaz 将 return false 因为它找到第一个 a,检查下一个 3 没有找到 z 并退出。
你的问题可以去掉末尾的return false,在内循环中加入与外循环相同长度的条件。
他对next的使用相当于上面的。这是一种将两件事联系在一起的方法。虽然它不必要地复杂,但我同意。
一种更简单的方法(假设您不想使用正则表达式)是只跟踪 'a'.
的最后一次出现
def nearby_az(string)
last_a = -4
string.chars.each_with_index do |c, i|
last_a = i if c == 'a'
return true if c == 'z' and i - last_a <= 3
end
return false
end
我正在上在线课程:
Write a method that takes a string and returns
true
if the letter"z"
appears within three letters after an"a"
. You may assume that the string contains only lowercase letters.
这是给出的解决方案:
def nearby_az(string)
i = 0
while i < string.length
if string[i] != "a"
i += 1
next
end
j = i + 1
while (j < string.length) && (j <= i + 3)
if string[j] == "z"
return true
end
j += 1
end
i += 1
end
return false
end
这个解决方案对我来说似乎过于复杂。具体来说,我不明白为什么需要 next
。我想知道是否有人可以帮助我理解这个功能。
我的解决方案似乎与我尝试过的测试一样有效,但我想知道其他解决方案是否更好,我的解决方案是否会出现我尚未遇到的问题。
def nearby_az(string)
i = 0
while i < string.length
while string[i] != "a"
i += 1
end
if string[i + 1] == "z" || string[i + 2] == "z" || string[i + 3] == "z"
return true
else
i += 1
end
return false
end
end
在原来的答案中,如果您删除 next
,i
索引将被假定代表一个 "a"
位置,即使它不是,并且将 return 一个错误的结果。
当你将一个像"b"
这样的字符串传递给你的代码时,它会进入一个无限循环,因为外部条件while i < string.length
无法控制:
while string[i] != "a"
i += 1
end
注意,一旦 i
超出字符串的最后位置,条件 string[i]
变为 nil
,并且 string[i] != "a"
将从那里得到满足。
如果字符串看起来像这样 "bbbbb..." 或像这样 "abb" - 即 - 1) 如果 string.length < 4 (no string[i+3]) 你的代码会崩溃 2) 如果字符串中没有 "a",您的代码将崩溃。 这里 "next" 派上用场了: "next" 的目的是跳过循环的其余部分并直接跳回到它的开头。因此,最初的解决方案将首先遍历字符,直到找到 "a" (跳过循环的另一部分不是)并且当且仅当它找到 "a" - 它会找到 "z".
因此,如 sawa 所述,您的循环不接受其中没有 a 的字符串。它也不理解具有多个 a 的字符串。例如 aaaaaaaz 将 return false 因为它找到第一个 a,检查下一个 3 没有找到 z 并退出。
你的问题可以去掉末尾的return false,在内循环中加入与外循环相同长度的条件。
他对next的使用相当于上面的。这是一种将两件事联系在一起的方法。虽然它不必要地复杂,但我同意。
一种更简单的方法(假设您不想使用正则表达式)是只跟踪 'a'.
的最后一次出现def nearby_az(string)
last_a = -4
string.chars.each_with_index do |c, i|
last_a = i if c == 'a'
return true if c == 'z' and i - last_a <= 3
end
return false
end