Về cơ bản, Unwind đúng là có nhiều cách khác nhau để triển khai một bộ ba; và đối với một bộ ba lớn, có thể mở rộng, các từ điển lồng nhau có thể trở nên cồng kềnh - hoặc ít nhất là không hiệu quả về dung lượng. Nhưng vì bạn chỉ mới bắt đầu, tôi nghĩ đó là cách tiếp cận dễ dàng nhất; bạn có thể viết mã đơn giản trie
chỉ trong vài dòng. Đầu tiên, một hàm để tạo 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_'}}}}
Nếu bạn không quen setdefault
, nó chỉ cần tra một khóa trong từ điển (tại đây letter
hoặc _end
). Nếu khóa có mặt, nó trả về giá trị được liên kết; nếu không, nó sẽ gán giá trị mặc định cho khóa đó và trả về giá trị ( {}
hoặc _end
). (Nó giống như một phiên bản của get
nó cũng cập nhật từ điển.)
Tiếp theo, một hàm để kiểm tra xem từ có trong bộ ba hay không:
>>> 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
Tôi sẽ để bạn chèn và loại bỏ như một bài tập.
Tất nhiên, gợi ý của Unwind sẽ không khó hơn nhiều. Có thể có một chút bất lợi về tốc độ là việc tìm kiếm nút phụ chính xác sẽ yêu cầu tìm kiếm tuyến tính. Nhưng tìm kiếm sẽ bị giới hạn ở số lượng ký tự có thể có - 27 nếu chúng tôi bao gồm _end
. Ngoài ra, không có gì để đạt được bằng cách tạo ra một danh sách lớn các nút và truy cập chúng theo chỉ mục như anh ấy gợi ý; bạn cũng có thể chỉ cần lồng các danh sách.
Cuối cùng, tôi sẽ nói thêm rằng việc tạo biểu đồ từ xoay chiều có hướng (DAWG) sẽ phức tạp hơn một chút, bởi vì bạn phải phát hiện các tình huống trong đó từ hiện tại của bạn chia sẻ hậu tố với một từ khác trong cấu trúc. Trên thực tế, điều này có thể trở nên khá phức tạp, tùy thuộc vào cách bạn muốn cấu trúc DAWG! Bạn có thể phải tìm hiểu một số thông tin về khoảng cách Levenshtein để làm đúng.