【问题标题】:Ruby anagram solver [closed]Ruby 字谜求解器 [关闭]
【发布时间】:2011-11-02 07:35:41
【问题描述】:

我想用 Ruby 编写一个字谜类型求解器,但它可以处理单词列表,就像这样。

单词列表是:

the
these
one
owner

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

【问题讨论】:

    标签: ruby algorithm search anagram


    【解决方案1】:

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

    【讨论】:

    • 好主意。多词字谜求解器怎么样?喜欢rrenaud => Ad Rerun?
    • @KimmoLehto 将句子拆分为数组,然后从数组中删除所有空格字符实例。之后,对数组进行排序,然后匹配它们。
    • @AshishPandey 您的意思并不完全清楚。当您说“拆分句子”时,没有所有可能句子的字典。如果您的意思是拆分输入句子并且您的意思是在空格处拆分,那么您只是在查找输入单词的字谜,而无需在单词之间交换字母。这不会经常产生结果。
    • @Adamantish 会有一本字典,问题说有一个单词列表。那是字典。所以,假设用户输入teehs,这个输入的拆分和排序数组将是[ 'e', 'e', 'h', 's', 't' ]。该程序还将有另一个多维散列,其中键是字典中的单词,值是它们的拆分和排序数组。然后我们可以简单地遍历散列的值并获得匹配的键。希望这是有道理的。
    • @AshishPandey 如果你尝试它,你会在那里遇到问题。首先,是的,排序后的数组是可以的,但它们需要成为键,因为每个数组都可能有多个单词。这就是直接查找单词的 O(1) 性能。但这仅有助于获得一个单词字谜。您需要找到所有 包含 您的输入字母的单词 - 不是哈希给出的完全匹配 - (stackoverflow.com/a/1924561/2772719 中的 trie 数据结构是最好的)然后您必须使用递归搜索剩下的字母。
    【解决方案2】:

    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。

    哈希的默认对象设置为空数组,这在某些情况下使编码更容易,因为您不必担心哈希会给您 nil。

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

    【讨论】:

    • 这与words.group_by {|word| word.chars.sort }相同
    • 酷,但实际上你需要这样做:@words_hash = words.group_by {|word| word.chars.sort}; @words_hash.default = []
    【解决方案3】:

    一种解决方案可能是:

    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
    

    【讨论】:

      【解决方案4】:

      我忍不住要解决这个红宝石测验:)

      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

      【讨论】:

      • 天哪,就是喜欢它!
      【解决方案5】:

      这可能就是您要查找的内容:Solving Anagrams In Ruby

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

      【讨论】:

        【解决方案6】:

        这和我的很相似。从字典文件中读取并将排序的字符作为数组进行比较。对预选的候选人进行排序。

        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
        

        【讨论】:

          【解决方案7】:
          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
          

          【讨论】:

            猜你喜欢
            • 2011-03-27
            • 2014-05-09
            • 2015-10-31
            • 1970-01-01
            • 2013-11-25
            • 1970-01-01
            • 2013-05-28
            • 2012-05-17
            • 2011-10-01
            相关资源
            最近更新 更多