题目
代码
from TrieNodeAbstract import TrieNodeAbstract
from ChildrenDictionary import ChildrenDictionary
import math
from typing import Dict, List, Union
# For help in traversing children
ALPHABET = 'abcdefghijklmnopqrstuvwxyz'
class TrieTree(TrieNodeAbstract):
def __init__(self, char='', value: str = ''):
'''
Initializes:
This node's char, `self._char`, ie. your current character in the key
This node's set of subtrees, 'children', using a dictionary
This node's value, `self._value` only set iff its a valid word in the dictionary
'''
self._value = value
self._children: ChildrenDictionary = ChildrenDictionary()
self._char = char
# TASK 1
def insert(self, word: str) -> None:
'''
Insert your new word, keep in mind, you must insert all child nodes
>>> trie = TrieTree()
>>> trie.insert("word")
>>> trie.insert("water")
>>> trie.insert("banana")
>>> "word" in str(trie)
True
>>> "water" in str(trie)
True
>>> "bob" in str(trie)
False
>>> "banana" in str(trie)
True
'''
cur = self
for c in word:
if c not in cur._children:
cur._children[c] = TrieTree()
cur = cur._children[c]
cur._char = c
cur._value = word
# raise NotImplementedError
# TASK 2
def __contains__(self, key: str):
'''
Returns True iff key is in tree, otherwise False
>>> trie = TrieTree()
>>> trie.insert("word")
>>> "word" in trie
True
>>> "other" in trie
False
'''
# TODO
cur = self
for c in key:
if c not in cur._children:
return False
cur = cur._children[c]
return (bool)(cur._value)
# raise NotImplementedError
# TASK 3
def __delitem__(self, key: str):
'''
Deletes entry in tree and prunes unecessary branches if key exists, otherwise changes nothing
>>> trie = TrieTree()
>>> trie.insert("word")
>>> "word" in trie
True
>>> del trie["word"]
>>> "word" in trie
False
>>> str(trie)
'TrieTree'
>>> trie.insert('ab')
>>> trie.insert('abs')
>>> str(trie)
'TrieTree\\n `- a\\n `- b : ab\\n `- s : abs'
>>> del trie['ab']
>>> str(trie)
'TrieTree\\n `- a\\n `- b\\n `- s : abs'
'''
# TODO
if not self.__contains__(key):
return False
cur = self
cur2 = self
last1 = self
last2 = self
ch = key[0]
for c in key:
if c in cur._children:
if(len(cur._children)>1):
cur2 = cur
ch = c
cur = cur._children[c]
if ((bool)(cur._value) & (last1 == self)):
last1 = cur
elif ((bool)(cur._value) & (last1 != self) & (last2 == self)):
last2 = cur
elif ((bool)(cur._value) & (last1 != self) & (last2 != self)):
last1 = last2
last2 = cur
if last2 == self:
if cur._children:
cur._value = ''
else:
cur2._children.pop(ch)
else:
if last2._children:
last2._value = ''
else:
last1._children = ChildrenDictionary()
# raise NotImplementedError
# TASK 4
def get_completion_words(self, pre_string):
word_list = []
# 叶节点退出递归,返回完整字符串
if self._value:
word_list.append(pre_string)
# return word_list
# 通过字典树的每个分支对之前的字符串进行补充
for c in self._children:
cur = self._children[c]
word_list.extend(cur.get_completion_words(pre_string + str(c)))
# 返回最终结果
return word_list
def sort(self, decreasing=False):
'''
Returns list of words in tree sorted alphabetically
>>> trie = TrieTree()
>>> trie.insert('banana')
>>> trie.insert('cherry')
>>> trie.insert('apple')
>>> trie.sort()
['apple', 'banana', 'cherry']
>>> trie.sort(decreasing=True)
['cherry', 'banana', 'apple']
'''
# TODO
if (decreasing == False):
ans = self.get_completion_words('')
ans.sort()
return ans
if (decreasing):
ans = self.get_completion_words('')
ans.sort(reverse=True)
return ans
# TASK 5
def autoComplete(self, prefix, N=10):
'''
if given a valid prefix, return a list containing N number of suggestions starting with that prefix in alphabetical order
else return an empty list
>>> trie = TrieTree()
>>> trie.insert('apple')
>>> trie.insert('dad')
>>> trie.insert('apples')
>>> trie.insert('application')
>>> trie.insert('app')
>>> trie.insert('about')
>>> trie.autoComplete('a')
['about', 'app', 'apple', 'apples', 'application']
>>> trie.autoComplete('a', N=2)
['about', 'app']
>>> trie.autoComplete('app')
['app', 'apple', 'apples', 'application']
>>> trie.autoComplete('c')
[]
>>> trie.autoComplete('d')
['dad']
'''
# TODO
cur = self
# last = cur
for c in prefix:
if c in cur._children:
# last = cur
cur = cur._children[c]
if (cur == self):
return []
a = cur.sort()
b = []
if len(a) <= N:
for str in a:
str = prefix + str
b.append(str)
else:
a = a[0:N]
for str in a:
str = prefix + str
b.append(str)
return b
# raise NotImplementedError
# TASK 6
def autoCorrect(self, word, errorMax = 2):
'''
Given a word, if misspelt return a list of possible valid words from the last valid prefix, with up to errorMax errors
>>> trie = TrieTree()
>>> trie.insert('dab')
>>> trie.autoCorrect('dod')
['dab']
>>> trie.autoCorrect('dod', errorMax=1)
[]
>>> trie.autoCorrect('dad', errorMax=1)
['dab']
>>> trie.insert('apple')
>>> trie.insert('dad')
>>> trie.insert('dude')
>>> trie.insert('apples')
>>> trie.insert('application')
>>> trie.insert('app')
>>> trie.insert('about')
>>> trie.insert("apples")
>>> trie.insert("application")
>>> trie.insert('app')
>>> trie.insert('apple')
>>> sorted(trie.autoCorrect('apl', errorMax=10))
['app', 'apple', 'apples', 'application']
>>> trie.autoCorrect('aboot')
['about']
>>> sorted(trie.autoCorrect('dea'))
['dab', 'dad']
>>> sorted(trie.autoCorrect('dod'))
['dab', 'dad', 'dude']
>>> sorted(trie.autoCorrect('dea', errorMax=3))
['dab', 'dad', 'dude']
'''
# TODO
i4 = 0
ans = []
cur22 = self
for c1 in word:
if c1 in cur22._children:
cur22 = cur22._children[c1]
i4 = i4+1
else:
break
becompared = cur22.sort()
word2 = word[i4:]
while becompared:
error = 0
len1 = len(word2)
len2 = len(becompared[0])
len3 = min(len1,len2)
len4 = max(len1,len2)
for i in range(len3):
if(word[i] != becompared[0][i]):
error = error+1
error = error+(len4-len3)
if error<=errorMax:
ans.append(becompared[0])
becompared.pop(0)
for i3 in range(len(ans)):
ans[i3] = word[:i4] + ans[i3]
return ans
# raise NotImplementedError
# TASK 7
def merge(self, otherTrie: TrieNodeAbstract):
'''
Merges another TrieTree into this one
>>> trie1 = TrieTree()
>>> trie2 = TrieTree()
>>> trie1.insert('amazing')
>>> trie2.insert('amazon')
>>> trie1.merge(trie2)
>>> 'amazon' in trie1
True
'''
# TODO
temp = otherTrie.sort()
while temp:
self.insert(temp[0])
temp.pop(0)
# raise NotImplementedError
def pPrint(self, _prefix="", _last=True, index=0):
'''
DONT CHANGE THIS
'''
ret = ''
if index:
ret = _prefix + ("`- " if _last else "|- ") + self._char
_prefix += " " if _last else "| "
if self._value:
ret += ' : ' + str(self._value)
ret += '\n'
else:
ret = _prefix + "TrieTree"
_prefix += " " if _last else "| "
ret += '\n'
child_count = len(self._children)
for i, child in enumerate(self._children):
_last = i == (child_count - 1)
ret += self._children[child].pPrint(_prefix, _last, index + 1)
return ret
def __str__(self):
return self.pPrint().strip()
if __name__ == '__main__':
import doctest
doctest.testmod()
'''
trie = TrieTree()
trie.insert('deal')
trie.insert('dear')
trie.insert('do')
trie.insert('heat')
trie.insert('hen')
trie.insert('he')
# trie.__str__()
# trie.__delitem__('he')
# a = trie.__contains__('he')
# a = trie.sort(True)
# a = trie.sort(False)
b = trie.autoComplete('he')
print(b)
'''
这个代码里面的task1到task7是需要完成的函数,其他的函数是不需要更改的。当然了,这个代码是不完整的,还有其他的一些.py文件,可以从这里下载完整的代码学习。
用python去对tire树进行操作,这个项目是很全面的。 谢谢使用