如何计算角色连续出现的次数

Moe*_*oe 1 ruby

我的代码适用于常规字符数

count = Hash.new(0)
str.each_char do |char|
    count[char] += 1 unless char == " "
end
count
Run Code Online (Sandbox Code Playgroud)

例如,"aaabbaaaaacccbbdddd"等于'a'= 8,'b'= 4,'c'= 3,'d'= 4.

我想做连续发生多少次.我想要的结果是:'a'= 3,'b'= 2,'a'= 5'c'= 3,'b'= 2,'d'= 4.我该怎么做?

saw*_*awa 7

"aaabbaaaaacccbbdddd".each_char.chunk(&:itself).map{|k, v| [k, v.length]}
# => [["a", 3], ["b", 2], ["a", 5], ["c", 3], ["b", 2], ["d", 4]]
Run Code Online (Sandbox Code Playgroud)

我对sawa和spickermann的解决方案进行了基准测试:

require 'benchmark/ips'

def sawa(string)
  string.each_char.chunk(&:itself).map{|k, v| [k, v.length] }
end

def spickermann(string)
  string.split(//).slice_when { |a, b| a != b }.map { |group| [group.first, group.size] }
end

Benchmark.ips do |x|
  string = "aaabbaaaaacccbbdddd"

  x.report("sawa") { sawa string }
  x.report("spickerman") { spickermann string }

  x.compare!
end

# Calculating -------------------------------------
#                 sawa     6.293k i/100ms
#          spickermann     4.447k i/100ms
# -------------------------------------------------
#                 sawa     75.353k (±10.4%) i/s -    371.287k
#          spickermann     48.661k (±12.0%) i/s -    240.138k
# 
# Comparison:
#                 sawa:    75353.5 i/s
#          spickermann:    48660.7 i/s - 1.55x slower
Run Code Online (Sandbox Code Playgroud)

  • 如果它解释了`chunk(&:self)`,这个答案会更好. (3认同)