2015-10-16 61 views
1

一個多維串頻陣列我要問用戶的字符串,程序應該命令字符串,並將其轉換成一個數組這樣排序在Ruby中

[["Letter", frequence]] 
[["a", 4],["b", 3],["c",3]] 

在情況下等於頻率,順序按字母順序排列。

我有這樣的代碼

puts "Write what you want" 
text = gets.chomp 
text.downcase! 
words = text.split("") 
print words 
frequencies = Hash.new(0) 
words.each do |word| 
    frequencies[word] += 1 
end 
frequencies = frequencies.sort_by {|x,y| y}.reverse! 
frequencies = frequencies.sort_by {|x| x[1]} 
frequencies.each do |word, freq| 
    puts word + " " + freq.to_s 
end 
+0

你的問題是什麼? – sawa

回答

2

這應該工作:

str = 'helloworld' 
frequency_hash = str.downcase.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 } 
# => {"h"=>1, "e"=>1, "l"=>3, "o"=>2, "w"=>1, "r"=>1, "d"=>1} 
frequency_hash.sort_by { |k,v| [-v, k] } 
# => [["l", 3], ["o", 2], ["d", 1], ["e", 1], ["h", 1], ["r", 1], ["w", 1]] 
+0

K,如果您使用了'group_by',我會使用您的解決方案。 –

1
str = "Baboon" 

h = str.downcase.each_char.group_by(&:itself) 
h.merge(h) { |_,a| a.size }.sort_by { |c,f| [-f, c] } 
    #=> [["b", 2], ["o", 2], ["a", 1], ["n", 1]] 

我們開始使用String#downcase

s = str.downcase 
    #=> "baboon" 

然後申請String#each_char

我們可以用String#chars

s.chars 
    #=> ["b", "a", "b", "o", "o", "n"] 

,但選擇的話,最好是使用一個枚舉,以避免臨時數組的創建。

枚舉的元件可以通過將其轉換爲一個數組中可以看出:

enum.to_a 
    #=> ["b", "a", "b", "o", "o", "n"] 

但我們不會做。接下來,我們就調用枚舉Enumerable#group_by

h = enum.group_by(&:itself) 
    #=> {"b"=>["b", "b"], "a"=>["a"], "o"=>["o", "o"], "n"=>["n"]} 

運營商&第一次使用Method#to_proc轉換的方法Object#itself(紅寶石2.2+),以一個進程,然後調用進程內。

然後,我們使用的Hash#merge使用該塊的形式:

{ |_,a| a.size } 

,以確定每一個鍵,其存在於被合併兩個散列值(其在這裏是當然,每個鍵的):

g = h.merge(h) { |_,a| a.size } 
    # => {"b"=>2, "a"=>1, "o"=>2, "n"=>1} 

最後,Enumerable#sort_by提供期望的排序:

g.sort_by { |c,f| [-f, c] } 
    #=> [["b", 2], ["o", 2], ["a", 1], ["n", 1]] 
+0

很好的解釋。但是,這樣一來,當頻率相等時(這個OP在他的問題中提到),鍵不會按字母順序排列。在你當前的實現中,輸入:'helloworld'將產生這個輸出:'[[「l」,3],[「o」,2],[「d」,1],[「w」,1] 「r」,1],[「e」,1],[「h」,1]]。但應該是:[[「l」,3],[「o」,2],[「d」,1],[「e」,1],[「h」,1],[ r「,1],[」w「,1]]。 –

+0

謝謝@KMRakibulIslam。我錯過了對二級排序鍵的引用。我修正了它,但現在它不那麼有趣。 –

0
mytext = "This is sample text to count all characters in string" 
myhash = mytext.downcase.each_char.with_object({}) { |c,h| (h[c] = h.fetch(c,0) + 1) if c =~ /[a-z]/ } 
> myhash.sort_by{|k,v| v}.reverse 
#=> [["t", 7], ["s", 5], ["i", 4], ["a", 4], ["e", 3], ["n", 3], ["r", 3], ["l", 3], ["c", 3], ["h", 2], ["o", 2], ["m", 1], ["u", 1], ["p", 1], ["x", 1], ["g", 1]]