2011-08-23 76 views
14

我想在Ruby中編寫一個anagram類型求解器,但它會對單詞列表起作用,就像這樣。話Ruby anagram求解器

名單是:

the 
these 
one 
owner 

我將允許用戶輸入一些字母,例如NOE,它會查的單詞列表的話,它可以使用用戶輸入的字母和會帶回one,如果他們輸入「eth」或甚至「the」,它將帶回the。我一直試圖想到一個有效的方法來做到這一點,但我一直在循環周圍的每個單詞,匹配單詞中的字母,檢查每個字母的單詞和兩個長度匹配。任何人都可以提供一個更好,更有效的方式來提供建議嗎?

回答

30

最大的想法是,排序當所有字謎是相同的。因此,如果你建立一個散列表(不知道Ruby是怎樣稱呼這些的),那麼這些鍵是排序詞,值是列出給定鍵的詞的列表,那麼你可以通過排序來快速找到字符串單詞,並在你的哈希中查找。

+1

好主意。多字謎語解算器如何?像'rrenaud' =>'Ad Rerun'? –

+0

@KimmoLehto將句子拆分爲數組,然後從數組中刪除空格字符的所有實例。之後,對數組進行排序然後匹配它們。 –

2

我無法抗拒解決這個紅寶石測驗:)

class String 

    def permutation(&block) 
    arr = split(//) 
    arr.permutation { |i| yield i.join } 
    end 
end 


wordlist = ["one", "two"] 

"noe".permutation do |i| 
    puts "match found: #{i}" if wordlist.include?(i) 
end 

的基本想法是,它創建和數組,並使用它的置換函數拿出結果。這可能效率不高,但我覺得它很優雅。 :d

+0

哦,我的,只是喜歡它! – thelastinuit

9

rrenaud的答案是偉大的,在這裏是如何構建紅寶石這樣的哈希爲例,給出命名的數組「words」包含所有的在你的字典裏的話:

@words_hash = words.each_with_object(Hash.new []) do |word, hash| 
    hash[word.chars.sort] += [word] 
end 

上面的代碼假定爲Ruby 1.9.2。如果您使用的是舊版本,則chars將不存在,但您可以使用.split('').sort

散列的默認對象被設置爲空數組,這使得在某些情況下編碼更容易,因爲您不必擔心散列給你零。

來源:https://github.com/DavidEGrayson/anagram/blob/master/david.rb

+3

這與'words.group_by {| word | |相同word.chars.sort}' –

+0

很酷,但實際上你需要這樣做:'@words_hash = words.group_by {| word | word.chars.sort}; @ words_hash.default = []' –

4

一種解決方案可能是:

def combine_anagrams(words) 
    output_array = Array.new(0) 
    words.each do |w1| 
    temp_array = [] 
    words.each do |w2| 
     if (w2.downcase.split(//).sort == w1.downcase.split(//).sort) 
     temp_array.push(w2) 
     end 
    end 
    output_array.push(temp_array) 
    end 
    return output_array.uniq 
end 
0
def combine_anagrams(words) 
    cp = 0 
    hash = Hash.new [] 
    words.each do |word| 
    cp += 1 
    (cp..words.count).each do |i| 
     hash[word.to_s.chars.sort.join] += [word] 
    end 
    hash[word.to_s.chars.sort.join] = hash[word.to_s.chars.sort.join].uniq 
    end 
    return hash 
end 
0

這裏是頗爲相似礦井。從字典文件中讀取並將已排序的字符作爲數組進行比較。排序是在預先選定的候選人上完成的。

def anagrams(n) 
    text = File.open('dict.txt').read 

    candidates = [] 
    text.each_line do |line| 
    if (line.length - 1) == n.length 
     candidates << line.gsub("\n",'') 
    end 
    end 

    result = [] 

    candidates.each do |word| 
    if word.chars.sort == n.chars.sort 
     result << word 
    end 
    end 

    result 

end