Çözme , bir trie gerçekleştirmenin birçok farklı yolu olduğu konusunda esasen doğrudur; ve büyük, ölçeklenebilir bir üçlü için, iç içe geçmiş sözlükler kullanışsız hale gelebilir - veya en azından alan verimsiz olabilir. Ama daha yeni başladığınız için, bence bu en kolay yaklaşım; trie
sadece birkaç satırda basit bir kod yazabilirsiniz. İlk olarak, trie'yi oluşturmak için bir fonksiyon:
>>> _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_'}}}}
Aşina değilseniz setdefault
, sözlükte bir anahtar arar (burada letter
veya _end
). Anahtar varsa, ilişkili değeri döndürür; değilse, bu tuşa varsayılan bir değer atar ve değeri ( {}
veya _end
) döndürür . (Bunun bir versiyonu gibi get
sözlüğü de günceller.)
Ardından, kelimenin trie içinde olup olmadığını test etmek için bir işlev:
>>> 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
Yerleştirme ve çıkarmayı bir alıştırma olarak size bırakacağım.
Elbette, Unwind'ın önerisi çok daha zor olmazdı. Doğru alt düğümü bulmanın doğrusal bir arama gerektirmesi bakımından hafif bir hız dezavantajı olabilir. Ancak arama, olası karakter sayısıyla sınırlı olacaktır - dahil edersek 27 _end
. Ayrıca, devasa bir düğüm listesi oluşturarak ve önerdiği gibi indeksle erişerek kazanılacak hiçbir şey yoktur; Listeleri iç içe geçirseniz iyi olur.
Son olarak, yönlendirilmiş çevrimsiz kelime grafiği (DAWG) oluşturmanın biraz daha karmaşık olacağını ekleyeceğim, çünkü mevcut kelimenizin yapıdaki başka bir kelimeyle bir son ek paylaştığı durumları tespit etmeniz gerekiyor. Aslında, DAWG'yi nasıl yapılandırmak istediğinize bağlı olarak bu oldukça karmaşık bir hal alabilir! Doğru yapmak için Levenshtein mesafesi hakkında bazı şeyler öğrenmeniz gerekebilir .