大量字符串快速匹配-字典树匹配

说明:

在本人的工作中遇到了这样的一个问题。需要用到字符串匹配的功能。
一边是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("???宁夏羊掌柜牧业有限公司"))

猜你喜欢

转载自blog.csdn.net/cyinfi/article/details/102077694
今日推荐