class TrieNode(object):#构建节点
def __init__(self):
self.path = 0
# 路过此节点几个
self.end = 0
# 以此为结尾的几个
self.map = [None for i in range(26)] #如果字符串种类特别多这样就不对了所以引出另一种方法用哈希表的方法表示路
# 每一个节点有26条路,26个字母
class Trie(object):
def __init__(self):#初始化创建一个头节点
self.root = TrieNode()
def insert(self, word):#插入方法
if word == None:#如果字符串不存在
return
node = self.root#来到头节点
for i in word:#遍历字符串
index = ord(i) - ord('a') #取出一个字符减去ASC2码 由字符对应走向那条路
# ord 为阿斯科码
if node.map[index] == None:#当前节点底下的路是不是空的
node.map[index] = TrieNode()#在这个节点下建出新节点
node = node.map[index]#跳到这个新节点上
node.path += 1
node.end += 1#当跳出循环时来到结尾end++
print('insert successful !!!')
def search(self, word):#word这个字符串之前被加入过几次返回次数
if word == None:
return 0
node = self.root#来到头节点
for i in word:#遍历字符串每个词
index = ord(i) - ord('a')#找路
if node.map[index] == None:#没有路
return 0
node = node.map[index]#有路就来到那个节点
return node.end #返回那个节点的end就是字符串出现的次数
# 如何区分 ‘be’ ,‘bef’
# 返回插入几次
def delete(self, word):#删除字符串
if self.search(word) != 0:#如果字符串存在
node = self.root#来到头节点
for i in word:#从头节点开始往下一个一个删
index = ord(i) - ord('a')
node.map[index].path -= 1#来到这条路让path-1
if node.map[index].path == 0: #当p为0这个节点就可以删掉了不用管这个节点的e值了 然后让这个节点指向空 JVM释放
# 本来原来就有一个 再删一个 就没了
# 变成0 代表不需要此节点了
node.map[index] = None
return
node = node.map[index]#来到下个路的节点
node.end -= 1 #字符串都删掉后尾结点end-1
# 不要把字母放到节点上
def prefixNumber(self, pre):#所有加入的字符串中有几个是以pre这个字符串作为前缀
if pre == None:
return
node = self.root
for i in pre:
index = ord(i) - ord('a')
if node.map[index] == None:
return 0#走着走着路没了
node = node.map[index]
return node.path #如果能走到返回头节点的pass值就是
if __name__ == '__main__':
ll=Trie()
ll.insert('abc')
ll.insert('abd')
ll.insert('ab')
print(ll.prefixNumber('a'))
print(ll.search('abc'))
print(ll.search('ab'))
print(ll.search('ad'))
ll.delete('abc')
print(ll.search('abc'))
print(ll.search('ab'))
print(ll.prefixNumber('a'))
输入的字符串是小写的a到z共26个字母,所以每个节点有26个路径。当字符串包含大写或者中文等等,就超出了26个字母了。 self.map = [None for i in range(26)] 这样的话就不对了。如何采用哈希表的方法构建路径?我没有一点思路,请大大们帮帮忙,看看在这个基础上怎么把路改成哈希表构建的路,还能实现原代码中的插入字符,搜索字符,删除字符,查询字符前缀的次数这四个功能、