-4

string があるとします"I am a good boy"。文字列に含まれる各文字の合計数が必要です。文字は大文字と小文字が区別されます。つまり、 2 つの異なる文字Dd見なす必要があります。

4

5 に答える 5

20
"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}
于 2013-04-20T20:21:04.997 に答える
15
a = "I am a good boy"

a.chars.group_by(&:chr).map { |k, v| [k, v.size] }
于 2013-04-20T20:42:13.400 に答える
8

これは回答を意図したものではなく、既存の回答への単なる追加です。

パフォーマンスが議論されたので、ここにいくつかのデータがあります。

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私のマシンで)

                           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)

と私s = s0 * 1000N = 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 のソリューションの複数のカウントは問題ありません。実際には、確かにそうです。

于 2013-04-20T23:49:17.823 に答える
6

私は使用します:

str = "私はいい子です"
str.scan(/[[:alpha:]]/i).each_with_object(Hash.new(0)) { |c, h| h[c] += 1}

どちらが返されますか:

{
    "私" => 1,
    "a" => 2,
    "m" => 1,
    "g" => 1,
    "o" => 3,
    "d" => 1,
    "b" => 1,
    "y" => 1
}

scan使用する正規表現は、カウントできる文字をすぐに決定するため、使用することを好みます。入力文字列に「I am a good boy.」が含まれている場合。他のソリューションのいくつかは、入力文字列に固有すぎて、予期しない文字に遭遇するたびに微調整が必​​要になるため、失敗します。入力が無菌であることはめったになく、現実の世界では、この種のコードは一般的な文に使用されることがわかっています。不要な文字を前もって無視することが重要です。


'Français'.scan(/[[:alpha:]]/i).each_with_object(Hash.new(0)) { |c, h| h[c] += 1}

どちらが返されますか:

{
    "F" => 1,
    "r" => 1,
    "a" => 2,
    "n" => 1,
    "ç" => 1,
    "私" => 1,
    "s" => 1
}
于 2013-04-20T22:04:17.083 に答える