使用Ruby计算句子中的字母数

使用Ruby计算句子中的字母数,ruby,string,Ruby,String,假设我有一个字符串“我是个好孩子”。我要字符串中每个字母的总数。信件区分大小写。i、 例如,D和D需要被视为两个不同的字符。我会使用: "I am a good boy".scan(/\w/).inject(Hash.new(0)){|h, c| h[c] += 1; h} # => {"I"=>1, "a"=>2, "m"=>1, "g"=>1, "o"=>3, "d"=>1, "b"=>1, "y"=>1} str = "I am a

假设我有一个字符串“我是个好孩子”。我要字符串中每个字母的总数。信件区分大小写。i、 例如,
D
D
需要被视为两个不同的字符。

我会使用:

"I am a good boy".scan(/\w/).inject(Hash.new(0)){|h, c| h[c] += 1; h}
# => {"I"=>1, "a"=>2, "m"=>1, "g"=>1, "o"=>3, "d"=>1, "b"=>1, "y"=>1}
str = "I am a good boy" str.scan(/[[:alpha:]]/i).each_with_object(Hash.new(0)) { |c, h| h[c] += 1 } 返回:

{ "I" => 1, "a" => 2, "m" => 1, "g" => 1, "o" => 3, "d" => 1, "b" => 1, "y" => 1 } { "F" => 1, "r" => 1, "a" => 2, "n" => 1, "ç" => 1, "i" => 1, "s" => 1 } { “F”=>1, “r”=>1, “a”=>2, “n”=>1, "ç" => 1, “i”=>1, “s”=>1 }
这不是一个答案,只是对现有答案的补充

因为讨论了性能,这里有一些数据

require 'benchmark'

s0 = "I am a good boy"
s = s0 * 1
N = 10000

Benchmark.bm(20) do | x |
  x.report('sawa') do
    N.times { s.scan(/\w/).inject(Hash.new(0)){|h, c| h[c] += 1; h} }
  end

  x.report('digitalross') do 
    N.times { s.chars.to_a.sort.group_by(&:chr).map { |k, v| [k, v.size] } }
  end

  x.report("digitalross'") do 
    N.times { s.chars.group_by(&:chr).map { |k, v| [k, v.size] } }
  end

  x.report('rubylovely') do
    N.times { s.gsub(/\s/,'').chars.with_object({}) {|c,ob| ob[c] = s.count(c)} }
  end
end
给出(
ruby 1.9.3p392
在我的机器上)

s=s0*1000
N=10
我得到

                           user     system      total        real
sawa                   0.340000   0.000000   0.340000 (  0.340617)
digitalross            0.380000   0.000000   0.380000 (  0.411393)
digitalross'           0.230000   0.010000   0.240000 (  0.243389)
rubylovely             6.530000   0.000000   6.530000 (  6.603198)

因此,对于非常短的字符串,RubyLovely解的多次计数不会有任何影响。事实上,确实如此。

我看不出拼写一段代码有什么错,所以任何Ruby程序员,包括新手,都很容易理解它。我想在那根绳子上做一次

所以,我喜欢这样:

s = "I am a good boy"

def count_word_characters(s)
    h = Hash.new(0)
    s.each_char do |char| 
        next unless char =~/\w/
        h[char] += 1
    end
    h
end
因为:

  • 很容易看到散列h是如何创建、填充和输出的
  • 哈希h在输入字符串的一次传递中填充
  • 很明显,我们跳过了非单词字符

@sawa不需要你的,因为ponited gem内部正在这样做。你可以复制这段代码作为答案。我将使用
gem
@Logan已经链接了这段代码。谁投了反对票?这个答案利用了reduce语句,效率更高。@RubyLovely google for
inject(Hash.new(0))
;这只是每个人计算频率的方式。@RubyLovely您的代码确实有效,但效率不高。字母“o”第一次出现时,它扫描整个字符串,统计所有o,并将结果(3)存储在散列中。在第二个“o”中,它也会做同样的事情,等等@RubyLovely:如果你要开始争论性能和效率,那么你应该用基准测试结果来支持它,否则这只是徒劳。在堆栈溢出时,你应该展示你为解决问题而编写的代码。这个问题在这里经常被问到,所以一些搜索应该已经找到了很多如何完成它的例子。这看起来确实像是家庭作业me@muistooshort,因为
a.chars.group_by(&:chr).map{k,v|[k,v.size]}
没有删除
white spaces
我想。”因为a.chars.group_by(&:chr).map{k,v|[k,v.size]}我想没有删除空白。“什么?!这与空间无关
chars
是字符串中单个字符的迭代器
group_by(&:chr)
按字符分组并返回一个散列,其中每个字符键具有相同字符出现的数组值<代码>映射将每个哈希值转换为字符和数组大小<代码>到a是不必要的,但可能是一种习惯<代码>排序很方便。@RubyLovely:我建议您自己尝试一下,并仔细查看有无
的结果。我还建议你在挖洞之前放下铲子。@RubyLovely:从
a.chars.to\u a.sort.group by…
你会得到相同的结果(顺序不同)。请离电脑远点,去做点别的事情,你的这些不专业的行为让你自己很尴尬。@RubyLovely:这与
a.chars.to\u.sort.group\u by…
a.chars.group\u by…
之间的区别没有任何关系,这就是锡人在你发疯并试图改变话题之前想告诉你的。我认为所有的挖掘工作都让你感到疲惫。你只进行了一次搜索,就像我对所有宪章所做的一样,除了
空格的计数。但是计算一下你创建一个新对象的次数?但我没有。这是我的代码到有效列表。我创建了多少次新对象?请详细解释这一点,以便我们都能从您的知识中受益,因为您知道这是一个糟糕的算法。顺便说一句,我已经删除了我的答案。但是,感谢您展示
基准测试
报告。
                           user     system      total        real
sawa                   0.600000   0.000000   0.600000 (  0.601734)
digitalross            0.790000   0.000000   0.790000 (  0.806674)
digitalross'           0.640000   0.010000   0.650000 (  0.651802)
rubylovely             0.570000   0.000000   0.570000 (  0.572501)
                           user     system      total        real
sawa                   0.340000   0.000000   0.340000 (  0.340617)
digitalross            0.380000   0.000000   0.380000 (  0.411393)
digitalross'           0.230000   0.010000   0.240000 (  0.243389)
rubylovely             6.530000   0.000000   6.530000 (  6.603198)
s = "I am a good boy"

def count_word_characters(s)
    h = Hash.new(0)
    s.each_char do |char| 
        next unless char =~/\w/
        h[char] += 1
    end
    h
end