为什么这个循环没有停止?

时间:2014-12-31 02:46:31

标签: ruby

我正在尝试取字符串“xxxyyyzzz”并将其拆分为一个组合相同字母的数组。所以我希望输出为[“xxx”,“yyy”,“zzz”]。我不确定为什么这段代码会继续循环。有什么建议吗?

def split_up(str)
  i = 1
  result = []
  array = str.split("")
  until array == []
    if array[i] == array[i-1]
      i += 1
    else
      result << array.shift(i).join("")
    end
    i = 1
  end
  result
end

puts split_up("xxxyyyzzz")

2 个答案:

答案 0 :(得分:5)

循环是因为您的until条件永远不会退出。当连续的字符匹配时,您正在递增i,但在循环结束时,您正在将i重置为1

如果您编辑此部分并添加以下行:

until array == []
  puts i  # new line

然后您会看到i始终为1,代码会一直打印1

删除行i = 1行,您将获得所需的结果。

此外,您可能有兴趣阅读Ruby字符串scan方法,模式匹配和捕获组,以及使用前瞻和后置零长度断言,它们可以匹配边界。

以下是我个人在字母边界处分割字符串的方法:

"xxxyyyzzz".scan(/(.)(\1*)/).map{|a,b| a+b }
=> ["xxx", "yyy", "zzz"]

scan方法正在执行此操作:

  1. .匹配任何字符,例如“x”,括号捕捉到它。
  2. \1*与任何时间段的上一次捕获相匹配,例如“xx”,括号捕捉到它。
  3. 因此$ 1匹配第一个字符“x”,$ 2匹配所有重复“xx”。
  4. 扫描块连接第一个字符及其重复,因此返回“xxx”。

答案 1 :(得分:0)

如上所述,这可以使用以下扫描解决:

def split_up(string)
  repeat_alphabets = /(\w)(\1*)/
  string.scan(repeat_alphabets).map do |match|
    match[0] << match[1]
  end
end

说明:

  1. 正则表达式匹配重复字符,但由于构造了正则表达式matches occur as pairs of the alphabet and remaining repeated instances
  2. m[0] << m[1]加入匹配项以形成必需的字符串。
  3. map将字符串组合成一个数组,并返回数组,因为它是最后一个语句。