探索AC自动机:多关键词搜索的原理与应用案例

引言

目前,大多数自由文本搜索技术采用类似于Lucene的策略,通过解析搜索文本为各个组成部分来定位关键词。这种方法在处理少量关键词时表现良好。但当搜索的关键词数量达到10万个或更多时,这种方法的效率会显著下降,尤其是在需要与词典进行详尽对比的场景中。本文将介绍的Aho-Corasick(AC)自动机作为多模式匹配中的经典算法,不仅能够处理大规模文本数据,还能确保搜索过程的实时性和准确性。

AC自动机:文本搜索的革命性工具

AC自动机可以被形象地比喻为一个超级找词机器。想象你手头有一本内容繁多的书籍和一份包含多个词语的列表,你的任务是快速找出所有这些词语在书中出现的位置。如果采用传统方法,即逐个词进行查找,工作量将会非常巨大。而AC自动机通过构建一种特殊的树状结构——前缀树或Trie,来极大地提升搜索效率。

AC自动机构建与搜索机制

构建前缀树(Trie)

AC自动机首先会根据所有关键词构建一个前缀树。这种树状结构的每个节点代表一个字母,并且每个字母都指向下一个可能的字母,从而形成一个连续的路径,表示一个或多个关键词的前缀

 70ea0465bcf34031b508feb8a2c9825f~tplv-73owjymdk6-jj-mark-v1_0_0_0_0_5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5Lqs5Lic5LqR5byA5Y-R6ICF_q75



****图片来源网络

失配指针(Fail指针)

在搜索过程中,如果当前路径上无法找到匹配的关键词,AC自动机会利用失配指针进行快速回溯。这些指针预先设置在树的每个节点上,指向其他可能的匹配路径,从而避免了从头开始搜索的低效性

066feda8031f42328863c20a1be25934~tplv-73owjymdk6-jj-mark-v1_0_0_0_0_5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5Lqs5Lic5LqR5byA5Y-R6ICF_q75 

****图片来源网络

实时搜索与高效报告

AC自动机在读取文本的同时,能够快速地遍历前缀树结构。一旦发现关键词出现在文本中,它能够立即报告这个词及其出现的位置。这种能力使得AC自动机能够一次性高效完成大量关键词的搜索任务

55de64d59f6d4e4e8e639e2ad4b9dcd1~tplv-73owjymdk6-jj-mark-v1_0_0_0_0_5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5Lqs5Lic5LqR5byA5Y-R6ICF_q75



****图片来源网络

算法核心组件与复杂度

核心组件:

goto(转跳):每个遇到的字符都会被提交给goto结构中的状态对象,以确定新的当前状态

fail(失败转移):如果没有找到匹配状态,算法会触发fail并回溯至深度更浅的状态,从那里继续搜索

output(输出):每当达到与整个关键词相匹配的状态时,该状态会被发送到输出集合中,完成扫描后即可读取这些匹配项

时间复杂度:

Aho-Corasick算法的时间复杂度为O(n),其中n是文本的长度。这意味着无论提供多少关键词,搜索的性能都将呈线性下降,与关键词的数量无关。

AC自动机的应用

AC自动机在多种场景下都能发挥重要作用,包括:

•在文本中查找并链接或突出显示关键词,提高信息的可检索性

•为纯文本添加语义,使文本内容更加丰富和有层次

•检查文本中的语法错误,通过与词典的对比来识别和纠正错误

应用案例: 使用Aho-Corasick算法来识别和高亮HTML文本中的关键词

本Java程序将演示如何使用Aho-Corasick自动机库来搜索和高亮HTML文本中的关键词。程序首先构建一个自动状态机,该状态机被训练识别一系列中文关键词。然后,程序将处理HTML文档,查找这些关键词的出现,并用<b>标签将它们包裹起来,以实现加粗显示的效果。

第一步:Maven依赖配置,引入Aho-Corasick自动机库

1<dependency> 2 <groupId>org.ahocorasick</groupId> 3 <artifactId>ahocorasick</artifactId> 4 <version>0.6.3</version> 5</dependency>

第二步:代码实现

1public class HighlightKeywordsInHtml { 2 3 public static void main(String[] args) { 4 // 定义HTML内容的字符串,包含了南京大学的介绍 5 String htmlContent = createHtmlContentForNanjingUniversity(); 6 // 创建Aho-Corasick Trie的构建器实例 7 Trie trie = buildAhoCorasickTrie(); 8 // 使用Trie实例处理HTML文本,获取匹配的Token集合 9 Collection<Token> tokens = trie.tokenize(htmlContent); 10 // 使用StringBuilder构建最终的HTML字符串,用于输出高亮的关键词 11 StringBuilder html = new StringBuilder(); 12 html.append("<html><body><p>"); 13 // 遍历Token集合 14 for (Token token : tokens) { 15 // 如果Token匹配关键词,则添加<b>标签以实现加粗效果 16 if (token.isMatch()) { 17 html.append("<b>"); 18 } 19 // 添加Token对应的文本片段 20 html.append(token.getFragment()); 21 // 如果Token匹配关键词,结束<b>标签 22 if (token.isMatch()) { 23 html.append("</b>"); 24 } 25 } 26 // 完成HTML字符串的构建 27 html.append("</p></body></html>"); 28 // 打印最终的HTML字符串,其中包含高亮显示的关键词 29 System.out.println(html); 30 } 31 32 private static String createHtmlContentForNanjingUniversity() { 33 // 此处添加创建南京大学HTML内容的方法实现 34 String speech = """ 35 <!DOCTYPE html> 36 <html lang="zh-CN"> 37 <head> 38 <meta charset="UTF-8"> 39 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 40 <title>南京大学简介</title> 41 <style> 42 body { 43 font-family: "微软雅黑", "宋体", Arial, sans-serif; 44 line-height: 1.6; 45 color: #333; 46 } 47 .university-intro { 48 text-align: justify; 49 margin-bottom: 2em; 50 padding: 1rem; 51 background-color: #f5f5f5; 52 border-radius: 5px; 53 } 54 </style> 55 </head> 56 <body> 57 <section class="university-intro"> 58 <h1>南京大学:百年名校,学术卓越</h1> 59 <p>南京大学,简称“南大”,位于中国江苏省南京市,是中国最顶尖的高等学府之一,拥有百年的办学历史和深厚的文化底蕴。作为中国教育部直属的全国重点大学,南大以其卓越的学术成就和教育质量闻名于世。</p> 60 <p>南京大学以其强大的师资力量和学术研究而著称,提供多元化的学科教育,包括自然科学、人文社会科学、工程技术等多个领域。学校注重培养学生的创新能力和国际视野,为国家和社会培养了大量杰出人才。</p> 61 <p>南大校园环境优美,历史与现代交融,是学术研究和知识探索的理想场所。学校在计算机科学、地球科学、化学等学科领域具有国际领先水平,并在推动科学技术进步和文化传承方面发挥着重要作用。</p> 62 </section> 63 </body> 64 </html> 65 """; 66 return speech; 67 } 68 69 private static Trie buildAhoCorasickTrie() { 70 return Trie.builder() 71 .ignoreOverlaps() // 设置不捕获重叠的关键词 72 .onlyWholeWords() // 仅匹配完整的单词 73 .ignoreCase() // 忽略关键词的大小写 74 .addKeywords(Arrays.asList("南京大学", "南大", "地球科学")) 75 .build(); // 构建Trie实例 76 } 77}

第三步:运行程序,符合预期

1<html><body><p><!DOCTYPE html> 2<html lang="zh-CN"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>南京大学简介</title> 7 <style> 8 body { 9 font-family: "微软雅黑", "宋体", Arial, sans-serif; 10 line-height: 1.6; 11 color: #333; 12 } 13 .university-intro { 14 text-align: justify; 15 margin-bottom: 2em; 16 padding: 1rem; 17 background-color: #f5f5f5; 18 border-radius: 5px; 19 } 20 </style> 21</head> 22<body> 23<section class="university-intro"> 24 <h1><b>南京大学</b>:百年名校,学术卓越</h1> 25 <p><b>南京大学</b>,简称“<b>南大</b>”,位于中国江苏省南京市,是中国最顶尖的高等学府之一,拥有百年的办学历史和深厚的文化底蕴。作为中国教育部直属的全国重点大学,南大以其卓越的学术成就和教育质量闻名于世。</p> 26 <p>南京大学以其强大的师资力量和学术研究而著称,提供多元化的学科教育,包括自然科学、人文社会科学、工程技术等多个领域。学校注重培养学生的创新能力和国际视野,为国家和社会培养了大量杰出人才。</p> 27 <p>南大校园环境优美,历史与现代交融,是学术研究和知识探索的理想场所。学校在计算机科学、<b>地球科学</b>、化学等学科领域具有国际领先水平,并在推动科学技术进步和文化传承方面发挥着重要作用。</p> 28</section> 29</body> 30</html> 31</p></body></html>

本文对Aho-Corasick(AC)自动机算法进行了抛砖引玉,揭示了其在处理大规模文本数据方面的卓越性能和应用潜力。若你渴望深入挖掘AC算法的精髓,进一步探索其高级应用和实现细节,建议参考以下的参考资料进行进一步的学习与挖掘。

参考资料

  1. http://cr.yp.to/bib/1975/aho.pdf

  2. https://github.com/robert-bor/aho-corasick

点赞
收藏

评论区

加载中...

相关推荐

SEC推广搜索引擎欺骗目前网易博客已经禁止该行为。

SEC是Search Engine Cheat,搜索引擎欺骗。SEC片面强调关键词的堆积,去欺骗搜索引擎提高排名。以下举例几种常见的SEC推广手段。    一、误导性关键词特点:在日志中使用与该日志内容毫不相干的误导性关键词来吸引查询该主题的访问者访问网站。     二、重复性关键词特点:在日志的标题或者正文中出现的关键词进行不合理

Elasticsearch由浅入深(十一)内核原理

倒排索引组成结构以及索引不可变原因对于倒排索引是非常适合用来进行搜索的它的结构:(1)包含这个关键词的documentlist(2)包含这个关键词的所有document的数量:IDF(inversedocumentfrequency)(3)这个关键词在每个document中出现的次数:TF

2020 7月 百度搜索词获取最新版

2020年7月相信大家很多人都获取不到百度的搜索词了百度五月份发出通告下线推广流量referer中搜索关键词!(https://img2020.cnblogs.com/blog/1615842/202008/161584220200803172115050181499106.png)目前获取SEM的搜索词(广告链接的)只能通过最新版的百度

RTSP协议网页无插件直播平台EasyNVR视频广场无法搜索纯数字关键词的通道,该如何解决的?

最近改版的新版EasyNVR我们发现界面中仍然保留了“视频广场”的显示项,通过视频广场可以查看不同通道的最新视频快照信息,也可以通过搜索方式展现特定的视频通道快照。最近测试中研发测试时,发现在视频广场使用搜索框搜索不到纯数字的关键词。!NVR10.png(https://imgconvert.csdnimg.cn/aHR0cDovLzEyMS40MC

Elasticsearch中的DocValues

搜索引擎的基本数据结构是反向索引,也就是为每个关键词建立了到文档的映射,然后所有的关键词是一个有序列表。搜索的时候,只要先从有序列表中匹配到关键词,就能搜索到包含该关键词的所有文档,反向索引的数据结构对于关键词搜索的场景是非常高效的。!(https://oscimg.oschina.net/oscnet/c540a67524fa4829b1

Serverless 实战:如何结合 NLP 实现文本摘要和关键词提取?

对文本进行自动摘要的提取和关键词的提取,属于自然语言处理的范畴。提取摘要的一个好处是可以让阅读者通过最少的信息判断出这个文章对自己是否有意义或者价值,是否需要进行更加详细的阅读;而提取关键词的好处是可以让文章与文章之间产生关联,同时也可以让读者通过关键词快速定位到和该关键词相关的文章内容。文本摘要和关键词提取都可以和传统的CMS进行结合,通过对文章