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

说明:

在本人的工作中遇到了这样的一个问题。需要用到字符串匹配的功能。
一边是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("???宁夏羊掌柜牧业有限公司"))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花咪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值