Ruby anagram求解器

时间:2011-08-23 21:15:11

标签: ruby algorithm search anagram

我想在Ruby中编写一个anagram类型求解器,但它会对一个单词列表起作用,就像这样。

单词列表是:

the
these
one
owner

我会允许用户输入一些字母,例如noe,它会在单词列表中搜索它可以使用用户输入的字母进行的单词,并将带回one,如果他们输入了“ eth“甚至”“它会带回the。我一直试图想出一个有效的方法来做到这一点,但我一直在循环每个单词,匹配单词中的一个字母,检查每个字母的单词和两个长度匹配。任何人都可以提出更好,更有效的方法吗?

7 个答案:

答案 0 :(得分:34)

最大的想法是所有字谜在排序时都是相同的。因此,如果您构建一个列表(不知道Ruby调用这些)的列表,其中键是排序的单词,而值是排序到给定键的单词列表,那么您可以通过排序来快速找到字谜单词并在你的哈希中查找。

答案 1 :(得分:10)

rrenaud的答案很棒,这里有一个如何在ruby中构造这样一个哈希的例子,给出一个名为“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

答案 2 :(得分: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

答案 3 :(得分: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

答案 4 :(得分:1)

这可能是您正在寻找的内容:Solving Anagrams In Ruby

这是另一种方法(它是最高响应):Anagram Solver In Python

答案 5 :(得分: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

答案 6 :(得分: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