【问题标题】:Best algorithm to find anagram of word from dictonary [closed]从字典中找到单词字谜的最佳算法[关闭]
【发布时间】:2013-12-19 20:31:14
【问题描述】:

我遇到了类似的问题

我有一个列表,它是包含数百万个单词的字典,我输入了一个像 OSPT 这样的单词,只有 2 个单词可以形成 STOP 和 POST.. 我想以优化的方式找出所有在字典中匹配的字谜词。

我解决了什么问题。

我给出了以下解决方案。我将取出单词并对其进行排列并检查该单词是否存在于字典中。但这 n*n 未优化。有什么办法可以解决这个问题

【问题讨论】:

  • @Bathsheba 这有什么帮助?

标签: java algorithm


【解决方案1】:

您按字母顺序对每个单词中的字符进行排序,以形成映射中的键,其值是该键的单词列表。

当您得到一个单词来查找其字谜时,您会按字母顺序对该单词中的字符进行排序并在地图中进行查找。

根据您的示例并添加单词 POOL,您会得到:

LOOP -> [LOOP, POOL, POLO]
OPST -> [STOP, POST]

Java 代码类似于:

public class AnagramGenerator
{
  private Map<String, Collection<String>> indexedDictionary;

  public AnagramGenerator(List<String> dictionary)
  {
    this.indexedDictionary = index(dictionary);
  }

  public Collection<String> getAnagrams(String word)
  {
    return indexedDictionary.get(sort(word));
  }


  private Map<String, Collection<String>> index(List<String> dictionary)
  {
    MultiMap<String, String> indexedDictionary = HashMultimap.create();

    for (String word : dictionary)
    {
      indexDictionary.put(sort(word), word);
    }

    return indexedDictionary.asMap();
  }

  private String sort(String word) 
  {
    List<Character> sortedCharacters= Arrays.asList(word.toCharArray());
    Collections.sort(sortedCharacters);

    StringBuilder builder = new StringBuilder();
    for (Character character : sortedCharacters)
    {
      builder.append(character);
    }

    return builder.toString();
  }
}

【讨论】:

    【解决方案2】:

    你可以这样做。

    • 对每个单词进行排序并将其添加到排序单词到实际单词的 MultiMap。
    • 通过首先对单词进行排序来查找每个单词以用作字谜。

    索引成本是一次,O(N),其中 N 是单词数。

    之后排序的成本是 O(M log M) 来对字母进行排序,其中 M 是字母的数量。与计算排列的成本相比,这非常便宜。

    顺便说一句,这种方法,单词只扫描一次,提前。

    【讨论】:

      【解决方案3】:

      这可以通过以下方式完成:

      对于给定的单词,记录其中的所有字符。例如对于OSTP,

      count['O'] = 1;
      count['S'] = 1;
      count['T'] = 1;
      count['P'] = 1;
      

      你可以像这样组成一个包含 26 个元素的数组。

      然后在遍历字典时,只需检查哪个单词的字符数相同。

      【讨论】:

        【解决方案4】:

        为了获得最佳速度,您可以将字符映射为唯一的素数,将它们相乘(确保有足够大的数字),然后将乘积用作存储有效排列的数字键。每个数字对于给定的排列集都是唯一的,因为字符形成了唯一的素数分解。

        给定一个输入词,重复该过程以获取该值,并直接使用该值访问字典。类似于排序的字符串解决方案,但节省了排序的开销并简化了键比较。

        参见此处以了解 c 中的相关解决方案 - Generate same unique hash code for all anagrams

        【讨论】:

          【解决方案5】:

          您可以预处理您的列表:将其中的任何单词替换为其排序的字谜(即 abacaba 变为 aaaabbc)。这个字符串唯一地表示任何单词,它是字典中单词的字谜。

          然后,当您收到查询时,对其中的字母进行排序并检查该单词是否在预处理字典中。

          【讨论】:

            猜你喜欢
            • 2011-02-07
            • 1970-01-01
            • 2021-10-16
            • 2010-12-01
            • 1970-01-01
            • 2019-02-02
            • 2011-08-08
            • 1970-01-01
            • 2010-09-25
            相关资源
            最近更新 更多