【AC Automation】AC自动机:多模板匹配

在优化程序过程中,发现网上的AC自动机代码存在问题。通过学习相关资料理解了AC自动机原理,并根据文章思路,用Python实现了AC自动机的算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天需要使用AC 自动机优化下程序,想从网上找现成的代码拿来直接用,然而在网上找到的代码都不对!!!也许是我的检索能力差吧!!!
好吧,我自己学习着写吧!
这里写链接内容
上面链接的讲解很好,读完之后就明白AC自动机了。但是作者提供的代码有错误,因而,根据文章的思路,写了基于Python的实现算法。

# -*- coding: utf-8 -*-
# @Time    : 7/5/2018 5:27 PM
# @Author  : saintfe
# @File    : ac_automation.py

def main():

    l = ['hert', 'this', 'ishe', 'hit','it']
    ac = AC(l)
    # ac.temp()
    res = ac.search("ithisherti")
    print(res)

    l = ['hers','his','he', 'she', 'zshe']
    ac = AC(l)
    res = ac.search('hiszshershe')
    print(res)



class AC(object):
    ''''''
    def __init__(self, word_list):
        self.root = Node('', 0)
        for word in word_list:
            self.add(word)
        self.make_fail()

    def add(self, word):
        node = self.root
        for idx, char in enumerate(word):
            idx += 1
            node = node.transfer.setdefault(char, Node(char, idx, node))
        node.output.append(word)

    def make_transfer(self, node, char):
        if char in node.transfer.keys():
            return node.transfer[char]
        elif node.level == 0:# root node
            return node # 遍历到根,返回根
        else:
            return self.make_transfer(self.find_fail(node), char)


    def find_parent(self, node):
        if node.parent:
            return node.parent
        return self.root
    def find_fail(self, node):
        if node.level == 0:
            return node
        return node.fail
    def make_fail(self):
        queue = [self.root]
        while queue:
            node = queue.pop(0)
            queue.extend(node.transfer.values())
            if self.find_parent(node).level == 0:
                node.fail = self.root
            else:
                node.fail = self.make_transfer( self.find_fail( self.find_parent(node) ), node.char ) 
                node.output.extend(node.fail.output) # 大胆些,没有重复



    def search(self, word):
        res = []
        node = self.root
        for char in word:
            node = self.make_transfer(node, char)
            if node.output:
                res.extend(node.output)
        return res

class Node(object):
    ''''''
    def __init__(self,char, level , node = None):
        self.char = char
        self.parent = node
        self.level = level
        self.transfer = {} # 转移函数
        self.fail = None
        self.output = []

if __name__ == '__main__':
    main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值