Ruby - App学院实践练习关于While循环中的条件

时间:2016-09-09 09:47:26

标签: ruby while-loop conditional-statements

我正在为第一次编码挑战完成App Academy's practice problems,并且对于为附近的#8提供的解决方案有疑问:

# Write a method that takes a string in and returns true if the letter
# "z" appears within three letters **after** an "a". You may assume
# that the string contains only lowercase letters.
#
# Difficulty: medium.

def nearby_az(string)
  idx1 = 0
  while idx1 < string.length
    if string[idx1] != "a"
      idx1 += 1
      next
    end

    idx2 = idx1 + 1
    while (idx2 < string.length) && (idx2 <= idx1 + 3)
      if string[idx2] == "z"
        return true
      end

      idx2 += 1
    end

    idx1 += 1
  end

  return false
end

# These are tests to check that your code is working. After writing
# your solution, they should all print true.

puts("\nTests for #nearby_az")
puts("===============================================")
    puts('nearby_az("baz") == true: ' + (nearby_az('baz') == true).to_s)
    puts('nearby_az("abz") == true: ' + (nearby_az('abz') == true).to_s)
    puts('nearby_az("abcz") == true: ' + (nearby_az('abcz') == true).to_s)
    puts('nearby_az("a") == false: ' + (nearby_az('a') == false).to_s)
    puts('nearby_az("z") == false: ' + (nearby_az('z') == false).to_s)
    puts('nearby_az("za") == false: ' + (nearby_az('za') == false).to_s)
puts("===============================================")

在第二个while循环中:

 while (idx2 < string.length) && (idx2 <= idx1 + 3)

为什么条件(idx2 < string.length)是必要的?我测试了没有它的代码,得到了相同的结果。

感谢您的协助。

2 个答案:

答案 0 :(得分:0)

  

为什么条件(idx2 < string.length)必要?

不是必要。当idx2超出字符串的边界时,它是一个防止无意义的循环迭代的守卫。

在超出字符串长度的位置处寻址字符将返回nil。 nil永远不会等于'z'。所以我们不妨在我们到达终点时停下来。这就是这里的检查,优化。

在其他情况下,越界访问通常是一种严重的攻击并导致各种问题(通常是崩溃)。所以总是这样做是有意义的。

答案 1 :(得分:0)

我知道这并没有回答你的确切问题,而其他人已经回答了这个问题,但正如编程的常见情况一样,这是一个更好的方法。您可以使用正则表达式轻松解决此问题

def nearby_az(string)
  !(string =~ /a\w{0,3}z/).nil?
end

正则表达式将匹配模式a,后跟0到3个字符,然后是z。如果这不匹配,=~运算符将返回nil,因此nil?方法返回true,这意味着该字符串没有附近的az,因此我们使用{{1要反转布尔值,此方法将返回!

如果匹配,false会返回第一个字符的索引,而不是=~,因此nil会返回nil?,我们会像以前一样将其反转返回false

认为这可能会有所帮助。