AC多模式匹配算法
建议:
学习ac算法最好的途径是看论文pdf_Efficient_String_Matching_An_Aid_to_Biblio
一、一般的搜索算法
keyword: { he, she, his, her }
text: "ushers"
- 总结:
如上图所示,一般的搜索过程需要每个关键字依次搜索,这是时间复杂度最高的算法。
当然,可以把每个关键字搜索过程优化为 KMP 或者 BM 算法,但仍然需要每个关键字都搜索一遍。
KMP、BM是单模匹配算法,使用多模匹配算法 AC 即可优雅解决此问题。
二、AC 算法的搜索过程
1.三个函数
goto 函数
fail 函数
output 函数
省略了 output(state) = empty 的情况
2.算法一 - 搜索过程
keyword: { he, she, his, her }
text: "ushers"
- 总结:
可以看到使用 AC 算法的搜索过程仅遍历了一次 text ,就找到了所有匹配 keyword。
搜索过程从状态0开始,通过 goto() 函数进行状态转换,每次转换状态都会执行 output() 函数,如果返回值不为空,说明匹配到关键字。goto() 函数返回 fail 的情况,执行 fail() 函数进行状态转换。
g(0,x) 没有失败的情况,至少会跳转到状态0
fail(x) 也没有失败的情况,至少会跳转到状态0
fail(x) 还存在优化的余地,假设 keyword 中没有 hers ,则这次 f(5) 就一次无用的跳转。
算法一:
三、生成 goto() fail() output() 函数的过程
1.算法二 - 生成 goto() 函数 和 不完整的 output() 函数
构造 goto() 函数的过程就是生成 goto() 前缀树的过程。从仅有一个点(状态为0)的前缀树开始,逐个添加关键字到前缀树即可。
1.添加 "he" 关键字
2.添加 "she" 关键字
]
3.添加 "his" 关键字
4.添加 "hers" 关键字
5.起点(状态0)作特殊处理,使 g(0, x) 永远不会返回 fail,x表示任意字符。
总结:
output() 函数目前还不完整,比如 output(5) 应该为 {she, he } 才能完整匹配所有关键字。所以还需要另外一个算法完成 output() 函数。
算法二
2.算法三 - 生成 fail() 函数 并补充 output() 函数
注:
为表述方便,此处虚拟了 state() 函数。
例如:state("he")表示字符串"he"在goto() 前缀树中所表示的状态值,并非真实存在的函数。
长度为1的字符串,其 fail() 返回值肯定是0。
情况1:2个字符串的 fail() 返回值
情况2:3个字符串的 fail() 返回值
情况3:4个字符串的 fail() 返回值
情况4:4个字符串的 fail() 返回值。
这里与情况3有一点区别,字符串 "ashe" 的最长子串 "she" 并不是关键字,所以我们认为 "he" 是 "ashe" 的最长子串,所以字符串 "ashe" 的 fail() 返回值是 "he" 的状态值。总结:
以上4种情况,间接表示了 fail() 函数生成过程,尤其是伪代码中while g(staet, a) = fail do state <- f(state)
的含义,即找到一个字符串的状态值,此字符串是当前关键词的最长后缀,同时又是其他关键词的前缀。然后 fail(s) 就等于我们找到的这个状态值。
算法三:
附件列表
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
· 程序员转型AI:行业分析
· 重磅发布!DeepSeek 微调秘籍揭秘,一键解锁升级版全家桶,AI 玩家必备神器!