删除相邻的重复子字符串

时间:2018-10-12 12:07:22

标签: ruby string

我正在尝试删除长度为k的重复的相邻子字符串,其中k是指字数。该代码应以

开头的递归方式工作

k = 1个字 取决于 k =字符串中的单词数

例如,

  

我今天早上坐下来写一篇文章,但发现 i i 没有进展

成为

  

我今天早上坐下来写一篇文章,但发现 i 毫无进展

我该如何实现?我可以通过以下方式实现1长度的相邻子字符串删除:

str.chunk{|n| n}.map(&:first)

2 个答案:

答案 0 :(得分:5)

s = "i sat down to write an article an article this morning but found that i i could make no progress"

max = s.scan(/\S+/).length
# => 20
1.upto(max).each_with_object(s) do
  |n, s| s.gsub!(/((?:\b\s*\S+){#{n}})\1/, '\1')
end
# => "i sat down to write an article this morning but found that i could make no progress"

顺便

"I like to move it move it, I like to move it move it"

将导致:

"I like to move it, I like to move it"

不是:

"I like to move it"

如您在评论中提到的,因为没有相邻的重复 除了上面的字符串(请注意逗号和空格)。

答案 1 :(得分:0)

我假设字符串除空格外不包含空格(不包括制表符,换行符,换行符,换页符等),并且单词用一个空格分隔,或者如果用多个空格分隔,则该字符串返回的单词之间只能包含一个空格。 (对于后者,有一种变通方法,但这并不是问题的中心。)

def remove_repeats(str)
  s = str.squeeze(' ')
  s.insert(0, ' ')
  change = ''
  until change.nil?
    change = s.gsub!(/(?:((?: \S+)+))\1/, '\1')
  end
  s[1..-1]
end

remove_repeats 'a a b a a b'              #=> "a b"
remove_repeats 'a a b c a a b c d'        #=> "a b c d"
remove_repeats ' c a a b a a b d a a b e' #=> " c a b d a b e"
remove_repeats 'aa a bb bb b'             #=> "aa a bb b"
remove_repeats 'a b c d e f'              #=> "a b c d e f"
remove_repeats ''                         #=> ""

正则表达式如下:“对于由空格和一串非空格组成的任何字符串,重复该字符串一次或多次,并将结果保存在捕获组1中。匹配捕获的内容组一次或多次,然后是捕获组的内容;如果gsub!至少进行了一次替换,则s被更新;否则gsub!返回nil。 ,在替换文本之前,我在字符串的开头插入了一个空格,然后在所有替换完成后将其删除。

/((?: \S+)+)\1/也适用于上述示例,但可能需要更多迭代才能获得解决方案。

我无法在所有情况下证明其有效。我邀请读者提供证明或反例。