用 Ruby 正则表达式从字符串中删除所有连续的字母

4

以下是来自Codeforces的问题:

Polycarp 经常思考生命的意义。他经常这样做,甚至在编辑器中键入时也是如此。每当他开始沉思时,他就无法完全集中精力,并重复按下只需要按一次的键。例如,他可能会输入"hhoow aaaare yyoouu",而不是"how are you"。

Polycarp 决定自动化这个纠正错误的过程。他决定编写一个插件到文本编辑器中,以删除一对连续相同的字母(如果有的话)。当然,这并不完全符合 Polycarp 的需求,但他必须从某些东西开始!

请帮助 Polycarp 编写主要的插件模块。您的程序应该从字符串中删除所有连续的相同字母对。如果删除后出现新的相同字母对,则程序应该继续删除它们。从技术上讲,它的工作应等同于以下内容:只要字符串包含一对连续相同的字母,该对就��该被删除。请注意,删除连续相同字母可以按任何顺序进行,因为任何顺序都会得到相同的结果。

以下是我的解决方案。由于某种原因,它未通过非常大的测试案例。我的解决方案似乎去除了比它应该去除的更多字母。这个正则表达式是否不正确?

str = gets.chomp

while str =~ /(.)\1/
  str.gsub!(/(.)\1+/,'')
end

puts str

编辑 -- 此解决方案不起作用,因为它会消除所有连续的字符组。 它应该只消除重复的部分。 如果我按照我认为是正确的方式处理,对于非常大的字符串,它会超时:

str = gets.chomp

while str =~ /(.)\1/
  str.gsub!(/(.)\1/,'')
end

puts str

你必须使用正则表达式吗?挤压方法怎么样?http://www.ruby-doc.org/core-1.9.3/String.html#method-i-squeeze - squiguy
看起来不错,但它只删除了其中一个重复项。我想要删除两个重复项。所以"aab"变成了"b"。 - ordinary
但是对于 'aaab' 应该怎么处理呢?它应该变成 'ab' 还是 'b' - mu is too short
什么意思超时了?你可以将其优化为仅匹配有效字符,如/([a-z])\1/i - squiguy
2个回答

8
为什么要使用正则表达式?
'foobar'.squeeze
=> "fobar"

"hhoow aaaare yyoouu".squeeze
=> "how are you"

squeeze是一个有用的工具,可以压缩所有字符或特定字符的连续出现。以下是文档中的一些示例:

"yellow moon".squeeze                  #=> "yelow mon"
"  now   is  the".squeeze(" ")         #=> " now is the"
"putters shoot balls".squeeze("m-z")   #=> "puters shot balls"

如果"aab"变成了"b",那么您就没有遵循问题中给出的示例,即"hhoow"变成了"how"。根据您的说法,它会变成"w",而"yyoouu"则会变成""。我认为您对问题的样本输入和输出不太理解,读入过多,导致了误解。


这是我在评论中建议的。很难说他到底想要什么。我现在正在努力想出一个连续的解决方案。 - squiguy
不,这个问题表述得很差。实际问题中引用的例子与我的说法一致。这是链接http://codeforces.com/problemset/problem/81/A。 - ordinary

1

哈,比我第一次阅读时想象的要难。那么怎么办呢?

s = "hhoow aaaareer yyoouu"
while s.gsub!(/(.)\1+/, '')
end
puts s

如果我正确理解问题,那么这将留下s == 'w'


我意识到这不起作用,因为您有像“aaab”这样的字符串,当正确的输出是“ab”时,它们最终会变成“b”。 - ordinary
在你的问题评论中,你说"aab"变成"b"是正确的。我认为你的评论是错误的。 - ThomasW
是的。"aab" 应该变成 "b"。但是 "aaab" 应该变成 "ab"。这是因为每个连续的字母对都应该被删除。 - ordinary
虽然很容易使其输出“ab”。只需使用第一个捕获组捕获的文本进行替换即可。 - nhahtdh
对不起,我不理解。我对正则表达式很陌生。 - ordinary
哦,你的意思是用'\1'替换。 - ordinary

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接