Это следующее, кажется, работает хорошо на небольшом словаре. Сортируя буквы в слове, легко проверить, являются ли два слова анаграммой. С этой отправной точки, это просто вопрос накопления слов в некотором роде. Не составит труда изменить это, чтобы сообщить обо всех совпадениях, а не только о первом
Если вам нужно добавить ограничения на количество букв, использование итераторов - удобный способ отфильтровать некоторые слова.
def wordIterator(dictionaryFilename):
with open(dictionaryFilename,'r') as f:
for line in f:
word = line.strip()
yield word
def largestAnagram(words):
import collections
d = collections.defaultdict(list)
for word in words:
sortedWord = str(sorted(word))
d[ hash(sortedWord) ].append(word)
maxKey = max( d.keys(), key = lambda k : len(d[k]) )
return d[maxKey]
iter = wordIterator( 'C:\\Python32\\megalist.txt' )
#iter = ( word for word in iter if len(word) == 5 )
print largestAnagram(iter)
Edit:
В ответ на комментарий hash(sortedWord)
- это оптимизация экономии места, возможно, преждевременная в этом случае, чтобы уменьшить sortedWord обратно до целого числа, потому что нам не важен ключ, пока мы можем всегда однозначно восстанавливайте все соответствующие анаграммы. Было бы одинаково правильно использовать просто sortedWord
в качестве ключа.
Аргумент key
для ключевого слова max
позволяет найти максимальный элемент в коллекции на основе предиката. Таким образом, оператор maxKey = max( d.keys(), key = lambda k : len(d[k]) )
является кратким выражением Python для ответа на запрос, с учетом ключей в словаре, с каким ключом связано значение максимальной длины? . Этот вызов max
в этом контексте мог бы быть записан (гораздо более многословно) как valueWithMaximumLength(d)
, где эта функция была определена как:
def valueWithMaximumLength( dictionary ):
maxKey = None
for k, v in dictionary.items():
if not maxKey or len(dictionary[maxKey]) < len(v):
maxKey = k
return maxKey