字典树:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
1 有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词。
2 1000万字符串,其中有些是重复的,需要把重复的全部去掉,保留没有重复的字符串。请怎么设计和实现?
3 一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词,请给出思想,给出时间复杂度分析。
Trie的核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
具体来说就是经常用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
Code,Cook,Five,File,Fat
其实就是字典套字典的形式~~还是很简单的,字典树其实就是省略了前缀的存储!作用还是很多的。
class Solution:
def __init__(self):
self.root = {}
self.word_end = "-1"
self.record = {}
def insert(self, s):
node = self.root
if s in self.record:
self.record[s] += 1
else:
self.record[s] = 1
for i in range(len(s)):
node.setdefault(s[i], {})
node = node[s[i]]
node[self.word_end] = True # 必须有这个的存在,否则难以 辨别是否存在 子字符串~~
def search(self, s):
node = self.root
for i in range(len(s)):
if s[i] not in node:
return False
else:
node = node[s[i]]
if self.word_end not in node:
return False
else:
return True
def dfs(self, node): # {'w': {'e': {'r': {'-1': True}, '-1': True}}}
for i in node:
if i == self.word_end: # 判断的是键
self.num += 1
continue
self.dfs(node[i]) # node[i]
def prefixNumber(self, s):
node = self.root
for i in range(len(s)):
if s[i] not in node:
return 0
else:
node = node[s[i]]
self.num = 0
self.dfs(node)
return self.num
def delete(self, s):
if s not in self.record:
return
self.record[s] -= 1
if self.record[s] > 0:
return
node = self.root
for i in range(len(s)):
node = node[s[i]]
node.pop(self.word_end) # 其他就不删除了,因为其他函数没有找到前缀也不会计入~
def trieU(self, operators):
# write code here
out = []
for operator in operators:
if operator[0] == "1":
self.insert(operator[1])
elif operator[0] == "2":
self.delete(operator[1])
elif operator[0] == "3":
if self.search(operator[1]):
out.append("YES")
else:
out.append("NO")
elif operator[0] == "4":
out.append("%s" % self.prefixNumber(operator[1]))
return out
ex = Solution()
print(ex.trieU([["1","qwer"],["1","qwe"],["3","qwer"],["4","q"],["2","qwer"],["3","qwer"],["4","q"]]))