繁体   English   中英

Ruby计数字符序列不使用正则表达式

[英]Ruby Counting chars in a sequence not using regex

在计算序列中的字符时需要有关此代码的帮助。

这就是我要的:

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]]

如果这个世界没有regexchunk

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM