Розмотувати по суті правильно, що існує багато різних способів реалізації трійки; а для великої масштабованої трійки вкладені словники можуть стати громіздкими - або, принаймні, неефективними. Але оскільки ви тільки починаєте роботу, я думаю, що це найпростіший підхід; ви можете зашифрувати просте trie
лише за кілька рядків. По-перше, функція побудови трійки:
>>> _end = '_end_'
>>>
>>> def make_trie(*words):
... root = dict()
... for word in words:
... current_dict = root
... for letter in word:
... current_dict = current_dict.setdefault(letter, {})
... current_dict[_end] = _end
... return root
...
>>> make_trie('foo', 'bar', 'baz', 'barz')
{'b': {'a': {'r': {'_end_': '_end_', 'z': {'_end_': '_end_'}},
'z': {'_end_': '_end_'}}},
'f': {'o': {'o': {'_end_': '_end_'}}}}
Якщо ви не знайомі setdefault
, він просто шукає ключ у словнику (тут letter
чи _end
). Якщо ключ присутній, він повертає пов'язане значення; якщо ні, він присвоює цьому ключу значення за замовчуванням і повертає значення ( {}
або _end
). (Це як версія, get
яка також оновлює словник.)
Далі функція перевірити, чи є слово в трійці:
>>> def in_trie(trie, word):
... current_dict = trie
... for letter in word:
... if letter not in current_dict:
... return False
... current_dict = current_dict[letter]
... return _end in current_dict
...
>>> in_trie(make_trie('foo', 'bar', 'baz', 'barz'), 'baz')
True
>>> in_trie(make_trie('foo', 'bar', 'baz', 'barz'), 'barz')
True
>>> in_trie(make_trie('foo', 'bar', 'baz', 'barz'), 'barzz')
False
>>> in_trie(make_trie('foo', 'bar', 'baz', 'barz'), 'bart')
False
>>> in_trie(make_trie('foo', 'bar', 'baz', 'barz'), 'ba')
False
Я вставлю і видаляю вас як вправу.
Звичайно, пропозиція розмотати не буде набагато складніше. Можливо, є невеликий недолік швидкості в тому, що для знаходження правильного підвузла потрібен буде лінійний пошук. Але пошук буде обмежений кількістю можливих символів - 27, якщо включити _end
. Крім того, нічого не можна отримати, створивши масивний список вузлів та отримати доступ до них за індексом, як він пропонує; Ви також можете просто вкласти списки.
Насамкінець додам, що створення спрямованого ациклічного графіка слів (DAWG) було б трохи складніше, тому що ви повинні виявити ситуації, в яких ваше поточне слово поділяє суфікс з іншим словом у структурі. Насправді це може бути досить складним, залежно від того, як ви хочете структурувати DAWG! Можливо, вам доведеться дізнатись деякі відомості про відстань Левенштейна, щоб виправити це правильно.