了解红宝石中的“下一步” - 比较解决方案

时间:2016-03-12 20:27:30

标签: ruby iteration next

我正在做一个在线课程:

  

编写一个带字符串的方法,如果字母true出现在 "z"之后的字母内,则返回"a"。您可以假设该字符串仅包含小写字母。

这是给出的解决方案:

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

3 个答案:

答案 0 :(得分:1)

在原始答案中,如果您删除next,则i索引将被假定为代表"a"位置,即使它不是,并且将返回错误的结果。

当您将类似"b"的字符串传递给代码时,它会进入无限循环,因为外部条件while i < string.length无法控制:

while string[i] != "a"
  i += 1
end

请注意,一旦i超出字符串的最后位置,条件string[i]就会变为nil,并且string[i] != "a"将从那里开始满足。

答案 1 :(得分:1)

如果字符串看起来像这样的“bbbbb ...”或者像这样的“abb”,你的解决方案将不起作用 - 那就是 - 1)如果string.length&lt;你的代码将崩溃4(没有字符串[i + 3]) 2)如果字符串中没有“a”,则代码将崩溃。 在这里,“下一个”派上用场: “下一步”的目的是跳过循环的其余部分并向右跳回到它的开头。因此,原始解决方案将首先查找字符,直到它找到“a”(跳过循环的其他部分不是),并且当且仅当它找到“a”时 - 它才会找到“z”。

答案 2 :(得分:1)

所以,正如sawa所说,你的循环不接受没有a的字符串。它也不理解具有多个a的字符串。例如aaaaaaaz将返回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