在学习Ruby的过程中,我遇到了这个练习。我正在尝试连续删除3个或更多相同的字符。测试用例输入:abbbaaccada输出:ccada输入:bbccdddcb输出:(空字符串)
到目前为止,我有不返回预期结果的解决方案:
def playground("abbbaaccada")
count = string.length
string.chars.each_with_index.map { |v, i| (v * (count - i)).capitalize }.join('')
end
output gives me
==> AaaaaaaaaaaBbbbbbbbbbBbbbbbbbbBbbbbbbbAaaaaaaAaaaaaCccccCcccAaaDdA
instead of
==> ccada
能请你指教吗?
编辑: 忘记添加不允许使用正则表达式
答案 0 :(得分:1)
这里有两个挑战:
这里是一种方法:
THREE_OR_MORE = /(.)\1{2,}/
def three_is_too_many(str)
if str.match? THREE_OR_MORE
str = three_is_too_many(str.gsub(THREE_OR_MORE, ''))
end
str
end
正则表达式查找任何字符('。'),然后查找其自身字符('\ 1'),两次或更多次('{2,}')。
然后例程要么a)删除三个或更多并再次测试,要么b)返回字符串。
答案 1 :(得分:1)
这是一个潜在的解决方案。以下方法搜索具有重复的数组的任何子序列,如果存在三个或更多个,则返回重复值的范围。
def find_3_or_more(ary)
ary.each_index do |i|
j = i + 1
while j < ary.length && ary[i] == ary[j]
j += 1
end
return (i...j) if j - i > 2
end
nil
end
此部分将目标字符串分成一个char数组,并反复将在标识为重复的范围内的字符切成薄片,直到没有重复为止,如nil
范围所示。
def delete_3_or_more(str)
ary = str.chars
while r = find_3_or_more(ary)
ary.slice!(r)
end
return ary.join
end
似乎可以完成您的测试用例。
答案 2 :(得分:0)
def recursively_remove_runs_of_3_or_more(str)
arr = str.chars
loop do
a = arr.slice_when { |a,b| a.downcase != b.downcase }.to_a
b = a.reject! { |e| e.size > 2 }
arr = a.flatten
break arr.join if b.nil?
end
end
recursively_remove_runs_of_3_or_more "abbbaaccada"
#=> "ccada"
这使用Enumerable#slice_when(MRI v2.2中的新功能)。请注意,Array#reject!在未进行任何更改时将返回nil
。
您也可以使用Enumerable#chunk_while(MRI v2.3中的新增功能)。只需替换:
a = arr.slice_when { |a,b| a.downcase != b.downcase }.to_a
具有:
a = arr.chunk_while { |a,b| a.downcase == b.downcase }.to_a
chunk_while
和slice_when
是阴和阳。
如果可以使用正则表达式并且在没有问题的情况下,您可以编写:
str = "abbbaaccada"
s = str.dup
loop { break(s) if s.gsub!(/(.)\1{2,}/, '').nil? }
#=> "ccada"
答案 3 :(得分:0)
(我想发表评论,但这还不允许我这样做。) 假设您正在尝试学习,我选择只给您一些提示,同时避免解决方案。
使用正则表达式或/和某些String方法可能会有更短的方法。但是,您说不能使用正则表达式。
我的建议是,仅尝试使用到目前为止介绍的部分来解决该问题。它可能不一定是最优雅的解决方案,但是您可以随着进度进行修改。正如其他人所建议的,递归可能是一个不错的选择。但是,如果您对此还不熟悉,则可以尝试对字符串进行切片并合并所需的部分。可以将其与无限循环结合使用,以检查新字符串是否满足您的条件:但是请考虑何时需要退出循环。
此外,在您的代码中:
v * (count - i)
String#*实际上为您提供了count - i
的{{1}}的副本,它们是串联在一起的。