Sarebbe bello sapere di più sui dati prima di suggerire un algoritmo, ma lascia supporre che le parole siano in inglese nel singolo caso.
Consente di assegnare a ciascuna lettera un numero primo compreso tra 2 e 101. Per ogni parola è possibile contare il suo "numero anagramma" moltiplicando i numeri corrispondenti della lettera.
Consente di dichiarare un dizionario di {numero, elenco} coppie. E una lista per raccogliere gli anagrammi risultanti in.
Quindi possiamo raccogliere anagrammi in due passaggi: basta attraversare il file e inserire ogni parola in un elenco di dizionari in base al suo "numero anagramma"; traverce la mappa e per ogni coppia di elenchi di lunghezza più di 1 memorizza i contenuti in un'unica grande lista di anagrammi.
UPDATE:
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
Naturalmente l'applicazione può essere ottimizzato ulteriormente. Ad esempio, non hai davvero bisogno di una mappa di anagrammi, solo un contatore andrebbe bene. Ma immagino che il codice mostri l'idea migliore così com'è.
Come stanno misurando "ottimale"? Il più veloce da implementare? Il più veloce da eseguire? Memoria meno utilizzata? Più preciso nel conteggio degli anagrammi? –
La complessità temporale è il parametro. – Spandan
Sembra che tu conosca già il metodo migliore: per ordinare in ordine alfabetico tutte le lettere di ogni parola, quindi confrontare le parole tra loro (per mezzo di ordinamento o hash). –