Ruby计数字符序列不使用正则表达式
在计算序列中的字符时需要有关此代码的帮助。
这就是我要的:
word("aaabbcbbaaa") == [["a", 3], ["b", 2], ["c", 1], ["b", 2], ["a", 3]] word("aaaaaaaaaa") == [["a", 10]] word("") == []
这是我的代码:
def word(str) words=str.split("") count = Hash.new(0) words.map {|char| count[char] +=1 } return count end
我得到了一句话(“aaabbcbbaaa”)=> [[“a”,6],[“b”,4],[“c”,1]],这不是我想要的。 我想计算每个序列。 我更喜欢没有正则表达式的解决方案。 谢谢。
按字符分割字符串,然后按字符串分组,然后计算字符串中的字符数:
def word str str .chars .chunk{ |e| e } .map{|(e,ar)| [e, ar.length] } end p word "aaabbcbbaaa" p word("aaaaaaaaaa") p word ""
结果:
[["a", 3], ["b", 2], ["c", 1], ["b", 2], ["a", 3]] [["a", 10]] []
如果您不想使用正则表达式,您可能只需要执行以下操作:
def word(str) last, n, result = str.chars.first, 0, [] str.chars.each do |char| if char != last result << [last, n] last, n = char, 1 else n += 1 end end result << [last, n] end
我想使用一些高阶函数来使这更简洁,但Ruby标准库中没有适当的函数。 Enumerable#partition
几乎可以做到,但并不完全。
我会做以下事情。 请注意, each_char
是一个较新的方法(Ruby 1.9?),可能在您的版本中不可用,因此在这种情况下坚持使用words=str.split("")
。
def word(str) return [] if str.length == 0 seq_count = [] last_char = nil count = 0 str.each_char do |char| if last_char == char count += 1 else seq_count << [last_char, count] unless last_char.nil? count = 1 end last_char = char end seq_count << [last_char, count] end [52] pry(main)> word("hello") => [["h", 1], ["e", 1], ["l", 2], ["o", 1]] [54] pry(main)> word("aaabbcbbaaa") => [["a", 3], ["b", 2], ["c", 1], ["b", 2], ["a", 3]] [57] pry(main)> word("") => []
另一个非正则表达式版本。
x = "aaabbcbbaaa" def word(str) str.squeeze.reverse.chars.each_with_object([]) do |char, list| count = 0 count += 1 until str.chomp!(char).nil? list << [char, count] end end p word(x) #=> [["a", 3], ["b", 2], ["c", 1], ["b", 2], ["a", 3]]
如果世界没有regex
和chunk
:
def word(str) a = str.chars b = [] loop do return b if a.empty? c = a.slice_before {|e| e != a.first}.first b << [c.first, c.size] a = a[c.size..-1] end end word "aaabbcbbaaa" # => [["a", 3], ["b", 2], ["c", 1], ["b", 2], ["a", 3]] word "aaa" # => [["a",3]] word "" # => []
这是另一种方式。 最初,我试图找到一个不需要将字符串转换为字符数组的解决方案。 在我看到@hirolau的答案之前,我无法想出任何体面的东西,我修改过:
def word(str) list = [] char = str[-1] loop do return list if str.empty? count = 0 count += 1 until str.chomp!(char).nil? list.unshift [char, count] char = str[-1] end end
您可以在扫描中使用此模式:
"aaabbcbbaaa".scan(/((.)\2*)/)
并计算所有组1的字符数
例:
"aaabbcbbaaaa".scan(/((.)\2*)/).map do |x,y| [y, x.length] end