2013-10-18 20 views
0

我有這個問題,哈希計算字母:使用Ruby來計算散列字母的數量?

#Counting with hashes! 
#Experiment by writing a couple of short programs that will use Hashes to count 
#objects by incrementing a key value. 
#Write a funcition that will count the number of letters in a phrase. 
#Example "cat in the hat" -> return: {"t"=>3, "h"=>2, "a"=>2, "i"=>1, "n"=>1, "e"=>1, "c"=>1} 
#From descending order. Largest to smallest. Do not include spaces. 

這裏是我的解決方案:

def count_letters(str) 
    count = Hash.new(0) 
    str.delete(" ").each_char { |letter| count[letter]+=1} 
    Hash[count.sort_by {|k,v| v}.reverse] 
end 

print count_letters("cat in the hat") 

爲了讓我按降序它排序,我只好把這個代碼片段:

Hash[count.sort_by {|k,v| v}.reverse] 

什麼是耐火材料我可以做什麼?有降序排序的另一種方法嗎?

有沒有更好的方法來做到這一點?

+0

哈希是隨機接入容器;對它們的內容進行排序是沒有意義的,並且沒有優勢,只是它更漂亮。相反,如果需要按照特殊順序對它們進行迭代,您可能會在檢索其內容時進行排序;實際上,有些語言不保留哈希的插入順序,因此在創建時總是會浪費時間排序。 –

+1

實際上它看起來像1.9,哈希將在迭代期間保持插入順序b/c它們由鏈表支持。 http://www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash/ –

+0

他們維護插入順序,直到添加另一個哈希條目,在*順序中不是*,然後是什麼?重新排序元素並創建一個新的散列? Ruby沒有一個排序哈希類,因爲再次,有什麼意義呢?這不是一個非常有用的功能,除非您稍後要迭代散列,類似於我們如何遍歷一個兩元素子數組的數組。而且,如果這是目標,那麼一個兩元素數組的數組將會減少開銷。 –

回答

2

避免反向通常我們會做這樣的:

def count_letters(s) 
    Hash[s.delete(' ').split('').group_by{ |c| c }.map{ |k, v| [k, v.size] }] 
end 

print count_letters("cat in the hat") 
# >> {"c"=>1, "a"=>2, "t"=>3, "i"=>1, "n"=>1, "h"=>2, "e"=>1} 

方便分類整理,然後:

def count_letters(s) 
    Hash[ 
    s.delete(' ') 
    .split('') 
    .group_by{ |c| c } 
    .map{ |k, v| [k, v.size] } 
    .sort_by{ |k, v| [-v, k] } 
    ] 
end 

print count_letters("cat in the hat") 
# >> {"t"=>3, "a"=>2, "h"=>2, "c"=>1, "e"=>1, "i"=>1, "n"=>1} 

的結果是按count遞減,並在count是相同的時候按字符遞增。

我正在排序的方法,但對於真正的工作,我不會做一個排序,除非我需要,然後我只做它需要排序的地方。爲每個散列做這件事是浪費,因爲它不會加快值的檢索。


從運行基準,我們知道using -v isn't the best way to reverse the sort order。使用v然後在結果數組中添加reverse實際上會更快。

+0

謝謝你非常好的解釋。 -v是什麼意思?它是否意味着與反向相同的東西? – hken27

+0

它表示'v'的負值。 –

2

您可以通過排序由-v

def count_letters(str) 
    counts = str.delete(' ').each_char.inject(Hash.new(0)) {|a,c| a[c] += 1; a} 
    Hash[counts.sort_by {|_,v| -v}] 
end 
0

解決方案:

def letter_count(word) 
    hash = {} 
    hash.default = 0 
    letters = word.downcase.chars 
    letters.each do |letter| 
     hash[letter] +=1 
    end 
    p hash 
end 

答:

letter_count("I love you") 
{"i"=>1, "l"=>1, "o"=>2, "v"=>1, "e"=>1, "y"=>1, "u"=>1}