class Trie:
def __init__(self):
self.N = 100000
# 存储所有字符
self.trie = [[0] * 26 for _ in range(self.N)]
self.count = [0] * self.N
self.index = 0
# 实现插入
def insert(self, word: str) -> None:
# 横轴表示格子,纵轴表示字符
# trie[i][j]表示要匹配的下一个格子序号
i = 0 # 格子从0开始
for s in word:
j = ord(s) - ord('a')
# 格子为0表示没匹配过
if self.trie[i][j] == 0:
# 使用的格子数+1
self.index += 1
self.trie[i][j] = self.index
i = self.trie[i][j]
# 统计i处的格子作为结尾的个数
self.count[i] += 1
# 实现搜索
def search(self, word: str) -> bool:
i = 0
for s in word:
j = ord(s) - ord('a')
# 格子为0表示没匹配过
if self.trie[i][j] == 0:
return False
# 否则匹配下一位
i = self.trie[i][j]
# 最后看i处格子被作为结尾的次数,只要不是0,都说明该字符串存在
return self.count[i] != 0
# 查找字典中是否有以prefix为前缀的字符串
def startsWith(self, prefix: str) -> bool:
i = 0
for s in prefix:
j = ord(s) - ord('a')
# 格子为0表示没匹配过
if self.trie[i][j] == 0:
return False
# 否则匹配下一位
i = self.trie[i][j]
# 与search函数的区别是,没有False,就是True
return True
# 数据结构,Trie树节点,表示一个字符
class TrieNode:
def __init__(self):
self.end = False # 标志该字符是否为某个单词的结尾
self.tns = [None] * 26 #记录该字符的后续字符,26个分支表示a-z,None表示无后续
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word: str) -> None:
i = self.root
for s in word:
j = ord(s) - ord('a')
if i.tns[j] == None:
i.tns[j] = TrieNode()
i = i.tns[j]
i.end = True
def search(self, word: str) -> bool:
i = self.root
for s in word:
j = ord(s) - ord('a')
if i.tns[j] == None:
return False
i = i.tns[j]
return i.end
def startsWith(self, prefix: str) -> bool:
i = self.root
for s in prefix:
j = ord(s) - ord('a')
if i.tns[j] == None:
return False
i = i.tns[j]
return True