文件中的所有字谜

时间:2013-06-01 12:05:03

标签: algorithm anagram

来源:Microsoft面试问题

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

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

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

4 个答案:

答案 0 :(得分:14)

在建议算法之前了解有关数据的更多信息会很好,但我们假设单个案例中的单词是英文的。

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

让我们声明{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

当然可以进一步优化实施。例如,你真的不需要一个字谜地图,只需一个计数器就行了。但我想这段代码最好地说明了这个想法。

答案 1 :(得分:3)

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

答案 2 :(得分:2)

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

  1. 将文件内容拆分为单词数组
  2. 创建一个将键字符串映射到字符串链接列表的HashMap
  3. 对于数组中的每个单词,对单词中的字母进行排序,并将其用作anagrams链接列表的键
  4. 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);
        }
    }
    

答案 3 :(得分:0)

与上述方法略有不同。而是返回anagrams的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]); 
        }
    }
}