说明:
在本人的工作中遇到了这样的一个问题。需要用到字符串匹配的功能。
一边是300字左右的句子,另一边是几个到几十个词的短语,然后过滤出包含短语的句子。
数量都在千万级别,最直接的想法肯定是两层for循环两两匹配,但是有点low。
在这实现了基于多叉树的树形匹配方式。(如果有问题,欢迎指正)
class Trie():
def __init__(self):
self.trie = {
"head":{
}}
def init_trie(self, path):
"""从文件初始树"""
path = r"D:/dict_words"
index = 0
with open(path, "r", encoding="utf-8") as reader:
for line in reader:
line = line.strip()
self.add_word(line)
index += 1
if index > 1000:
break
print("over")
def add_word(self, word):
"""添加字符串"""
word = word.split("\t")[1]
word = word.strip()
word_list = list(word)
word_list.append("<end>")
word_list_len = len(word_list)
index = 0
tmp_index_dict = self.trie["head"]
while index < word_list_len:
if word_list[index] in tmp_index_dict:
tmp_index_dict = tmp_index_dict[word_list[index]]
index += 1
else:
if index < word_list_len - 1:
tmp_index_dict[word_list[index]] = {
word_list[index + 1]:{
}}
else:
tmp_index_dict[word_list[index]] = {
}
tmp_index_dict = tmp_index_dict[word_list[index]]
index += 1
def is_contain_word_wap(self, sent):
"""判断句子是否包含词典中的词"""
print(sent)
if sent == None or len(sent) == 0:
return False
res = False
for i in range(len(sent)):
tmp = sent[i:]
if self.is_contain_word(tmp):
res = True
break
return res
def is_contain_word(self, sent):
"""判断一个句子是否包含词典中的词 - 需要从开头开始有匹配项"""
word_list = list(sent)
word_list_len = len(word_list)
index = 0
tmp_index_dict = self.trie["head"]
while index < word_list_len:
if word_list[index] in tmp_index_dict:
tmp_index_dict = tmp_index_dict[word_list[index]]
index += 1
else:
break
if "<end>" in tmp_index_dict and index > 0:
return True
return False
def is_in_dict(self, word):
"""是否在词典中"""
word_list = list(word)
word_list_len = len(word_list)
index = 0
tmp_index_dict = self.trie["head"]
while index < word_list_len:
if word_list[index] in tmp_index_dict:
tmp_index_dict = tmp_index_dict[word_list[index]]
index += 1
else:
break
if "<end>" in tmp_index_dict and index > 0:
return True
return False
if __name__ == "__main__":
print("running ")
trie = Trie()
trie.init_trie("")
print(trie.is_in_dict("宁夏羊掌柜牧业有限公司"))
print(trie.is_in_dict("宁夏?掌柜牧业有限公司"))
print(trie.is_in_dict("??宁夏羊掌柜牧业有限公司"))
print(trie.is_contain_word_wap("宁夏羊掌柜牧业有限公司???"))
print(trie.is_contain_word_wap("???宁夏羊掌柜牧业有限公"))
print(trie.is_contain_word_wap("???宁夏羊掌柜牧业有限公司"))