Все анаграммы в файле
Источник : Microsoft Интервью Вопрос
нам предоставляется файл, содержащий слова.Нам нужно определить все анаграммы, присутствующие в нем .
может кто-то предложить наиболее оптимальный алгоритм для этого.
единственный способ я знаю сортировка всех слов, затем проверка .
4 ответов
хорошо бы знать больше о данных прежде чем предлагать алгоритм, но давайте просто предположим, что слова в английском языке в одном случае.
давайте назначим каждой букве простое число от 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
конечно реализация может быть оптимизирована дальше. Например, вам действительно не нужна карта анаграмм, просто счетчики будут в порядке. Но я думаю, что код лучше всего иллюстрирует эту идею.
вы можете использовать "Триэс".Trie (производное от извлечения) - это дерево поиска несколькими способами. Пытается использовать алгоритмы сопоставления шаблонов. Основное использование-создание программ проверки орфографии, но я думаю, что это может помочь вашему делу.. Посмотрите на эту ссылку http://ww0.java4.datastructures.net/handouts/Tries.pdf
Я просто сделал это не так давно, по-другому.
- разделить содержимое файла на массив слов
- создайте HashMap, который сопоставляет строку ключа со связанным списком строк
- для каждого слова в массиве отсортируйте Буквы в слове и используйте это как ключ к связанному списку анаграмм
public static void allAnagrams2 (строка s) { String[] input = s.toLowerCase ().replaceAll ("[^a-z^\s]", "").сплит("\с"); HashMap> hm = новый 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);
}
}
немного отличается от подхода, описанного выше. Вместо этого возвращаем хеш-карту анаграмм.
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]);
}
}
}