文件中的所有字谜

Posted

技术标签:

【中文标题】文件中的所有字谜【英文标题】:All anagrams in a File 【发布时间】:2013-05-28 04:10:24 【问题描述】:

来源:微软面试问题

我们得到一个包含单词的文件。我们需要确定其中存在的所有字谜。

有人可以建议最佳算法来做到这一点。

我知道的唯一方法是 对所有单词进行排序,然后检查。

【问题讨论】:

他们如何衡量“最佳”?最快实施?跑得最快?使用最少的内存?计算字谜最准确? 时间复杂度是参数。 您似乎已经知道最好的方法:按字母顺序对每个单词中的所有字母进行排序,然后将单词相互比较(通过排序或哈希)。 有更好的方法吗? 可能重复 - ***.com/questions/18781106/… 【参考方案1】:

最好在建议算法之前了解更多有关数据的信息,但我们假设单词在单一情况下是英文的。

让我们为每个字母分配一个从 2 到 101 的素数。对于每个单词,我们可以通过将其字母对应的数字相乘来计算它的“字谜数字”。

让我们声明一个 number, list 对的字典。以及一个用于收集结果字谜的列表。

那么我们可以分两步收集字谜:简单地遍历文件,将每个单词根据其“字谜编号”放入字典列表中;遍历地图,对于长度超过 1 的每个对列表,将其内容存储在一个大字谜列表中。

更新:

import operator

words = ["thore", "ganamar", "notanagram", "anagram", "other"]

letter_code = 'a':2, 'b':3, 'c':5, 'd':7, 'e':11, 'f':13, 'g':17, 'h':19, 'i':23, 'j':29, 'k':31, 'l':37, 'm':41, 'n':43, 
            'o':47, 'p':53, 'q':59, 'r':61, 's':67, 't':71, 'u':73, 'v':79, 'w':83, 'x':89, 'y':97, 'z':101

def evaluate(word):
    return reduce( operator.mul, [letter_code[letter] for letter in word] )

anagram_map = 
anagram_list = []
for word in words:
    anagram_number = evaluate(word)
    if anagram_number in anagram_map:
        anagram_map[ anagram_number ] += [word]
    else:
        anagram_map[ anagram_number ] = [word]

    if len(anagram_map[ anagram_number ]) == 2:
        anagram_list += anagram_map[ anagram_number ] 
    elif len(anagram_map[ anagram_number ]) > 2:
        anagram_list += [ word ]

print anagram_list

当然可以进一步优化实现。例如,您实际上并不需要字谜图,只需一个计数器就可以了。但我想代码最能说明这个想法。

【讨论】:

我不确定我是否遵循这个。您能否在 UPDATE 中发布示例实现。 我现在关注它。现在我不确定的一件重要事情是它的正确性。两组不同数字的乘积不能相同吗? 这个答案很特别。太棒了。 @akalenuk 你如何处理溢出? 太棒了,我在想一个很好的哈希函数来解决类似的问题。【参考方案2】:

您可以使用“Tries”。trie(源自检索)是一种多路搜索树。尝试使用模式匹配算法。它的基本用途是创建拼写检查程序,但我认为它可以帮助你的情况.. 看看这个链接http://ww0.java4.datastructures.net/handouts/Tries.pdf

【讨论】:

不,不会。这个问题的设计目的是让人们偏离轨道并开始思考 Tries。尝试帮助精确匹配而不是字谜。 可以使用trie,但是和使用hashmap没有任何区别,仍然需要对每个单词进行排序并填充到trie或hashmap中。【参考方案3】:

不久前我刚刚以不同的方式做了这个。

    将文件内容拆分为单词数组 创建一个将键字符串映射到字符串链表的 HashMap 对于数组中的每个单词,对单词中的字母进行排序并将其用作变位词链接列表的键

public static void allAnagrams2(String s) String[] input = s.toLowerCase().replaceAll("[^a-z^\s]", "").split("\s"); HashMap> hm = new HashMap>();

    for (int i = 0; i < input.length; i++) 
        String current = input[i];

        char[] chars = current.toCharArray();
        Arrays.sort(chars);
        String key = new String(chars);

        LinkedList<String> ll = hm.containsKey(key) ? hm.get(key) : new LinkedList<String>();
        ll.add(current);

        if (!hm.containsKey(key))
            hm.put(key, ll);
    

【讨论】:

与 akalenuk 的答案相比,时间复杂度要高得多。因为它涉及到排序。【参考方案4】:

与上述方法略有不同。而是返回一个字谜的 Hashmap。

Public static Hashmap<String> anagrams(String [] list)

    Hashmap<String, String> hm = new Hashmap<String, String>();
    Hashmap<String> anagrams = new Hashmap<String>();

    for (int i=0;i<list.length;i++)
        char[] chars = list[i].toCharArray();
        Arrays.sort(chars);
        String k = chars.toString();
        if(hm.containsKey(k))
            anagrams.put(k);
            anagrams.put(hm.get(k));
        else
            hm.put(k, list[i]); 
        
    

【讨论】:

以上是关于文件中的所有字谜的主要内容,如果未能解决你的问题,请参考以下文章

javascript [438。查找字符串中的所有字谜] #tags:leetcode

编写一个字谜查找器(来自 txt 文件中的单词列表)[重复]

javascript中的字谜查找器

检查文本文件中的完全匹配

代码高尔夫:查找所有字谜

使用python中的递归解决方案在字符串列表中查找字谜