Совершенно бессмысленно работать над ускорением инициализации Trie, прежде чем вы решите, работает ли ваше средство поиска.
В коде, на который ссылается @unutbu, почемувы представляете, что это дерьмо с {'end':False}
и pt['end']=True
?
Вот некоторые тестовые данные для вас:
words_to_insert = ['foo', 'foobar']
queries_expecting_true = words_to_insert
queries_expecting_false = "fo foe foob food foobare".split()
И вот еще одна мысль: вы не даете никаких указаний, что вы хотитечто-то большее, чем способность определять, присутствует ли слово запроса или нет.Если это правильно, вам следует рассмотреть возможность сравнения вашего собственного дерева с встроенным set
.Критерии: скорость загрузки (подумайте о том, чтобы сделать это с помощью pickle), скорость запроса и использование памяти.
Если вы хотите получить больше, чем bool
, то замените dict
на set
и повторитепрочитайте этот ответ.
Если вы действительно хотите искать слова во входной строке, то вы можете рассмотреть код, на который ссылается @unutbu, с исправленными ошибками и некоторыми ускорениями в функции find
(оценка len(input)
только один раз, используйте xrange
вместо range
(Python 2.x)) и удалите ненужные TERMINAL: False
записи:
TERMINAL = None # Marks the end of a word
def build(words, trie=None): # bugs fixed
if trie is None:
trie = {}
for word in words:
if not word: continue # bug fixed
pt = trie # bug fixed
for ch in word:
pt = pt.setdefault(ch, {})
pt[TERMINAL] = True
return trie
def find(input, trie):
len_input = len(input)
results = []
for i in xrange(len_input):
pt = trie
for j in xrange(i, len_input + 1):
if TERMINAL in pt:
results.append(input[i:j])
if j >= len_input or input[j] not in pt:
break
pt = pt[input[j]]
return results
или вы можете посмотреть на быструю реализацию Дэнни Ю алгоритма Aho-Corasick .