字符串匹配算法(AC自动机 Aho-Corasick)
文章目录
- 1. 多模式串匹配
- 2. 经典多模式串匹配--AC自动机
- 2.1 AC自动机构建
- 2.2 在AC自动机上匹配主串
- 2.3 复杂度分析
- 3. python包
1. 多模式串匹配
- 前面学的BF、RK、BM、KMP都是单模式串匹配算法(一个模式串,一个主串)
- 多模式串匹配,即在一个主串中查找多个模式串(Trie树是多模式匹配)
- 比如实现多个敏感词过滤;单模式需要一遍遍的,扫描,过滤,扫描,过滤;多模式扫描一遍,过滤完成
2. 经典多模式串匹配–AC自动机
AC自动机算法(Aho-Corasick算法),是在Trie树之上,加了类似 KMP 的 next 数组。
class ACNode //AC自动机的Trie树节点类,假设只有26个字母的数据集
{public:char data;ACNode *children[charNum];size_t count; //记录这个节点被多少个单词占用bool isEndOfWord;//是否是一个单词的结束字符size_t freq; //单词插入的频次int length; //当isEndOFWord为True时,记录模式串长度ACNode *fail; //失败指针ACNode(char ch = '/'):data(ch), isEndOfWord(false),count(0), freq(0),length(-1),fail(NULL){memset(children,0,sizeof(ACNode*) * charNum);}~ACNode(){}
};
2.1 AC自动机构建
- 1,将多个模式串插入Trie树。
- 2,在Trie树上构建失败指针(相当于KMP中的失效函数 next 数组)
void buildFailPointer()
{queue<ACNode*> ACNode_queue;ACNode_queue.push(root);ACNode *p, *pchild, *q, *qchild;int i;while(!ACNode_queue.empty())//用队列按层遍历{p = ACNode_queue.front();//队首的节点pACNode_queue.pop();for(i = 0; i < charNum; ++i){pchild = p->children[i];//找到p的非空子节点pcif(pchild == NULL)continue;if(p == root)pchild->fail = root;else{q = p->fail; //q为p的失效指针while(q != NULL) //q不为空{qchild = q->children[pchild->data-'a'];//字符等于pc的qcif(qchild != NULL)//qc存在{pchild->fail = qchild;//链接pc失败指针到qcbreak;//找到了就跳出循环}q = q->fail;//qc不存在,就再去上一个失效点找}if(q == NULL)//最后找到root处还没找到pchild->fail = root;//pc的失效指针指向root}ACNode_queue.push(pchild);//把p的非空子节点pc入队}}
}
2.2 在AC自动机上匹配主串
void match(const string &maintext) //maintext是主串
{int n = maintext.size();ACNode *p = root, *temp;//模式串从root开始int index, pos;for(int i = 0; i < n; ++i)//主串从i=0开始{index = maintext[i]-'a';//子节点下标while(p->children[index] == NULL && p != root){//p不为root,且 子节点为空(找不到那个i对应的字符)p = p->fail; //失败指针发挥作用的地方}p = p->children[index];if(p == NULL)p = root; //如果没有匹配的,从root开始重新匹配temp = p;while(temp != root)//打印出可以匹配的模式串{if(temp->isEndOfWord == true){pos = i-temp->length+1;cout << "Found " << maintext.substr(pos,temp->length) << " at ""position(start from 0) "<< pos << " at " << maintext << endl;}temp = temp->fail;}}
}
主程序
Trie textlib;
string a("abcd"), b("bcd"), c("c");
textlib.insert(a);
textlib.insert(a);
textlib.insert(b);
textlib.insert(c);
textlib.buildFailPointer();
textlib.match("abcdc");
在Trie树基础上的AC自动机完整代码(请点击查看)
2.3 复杂度分析
- 构建AC自动机
- 构建Trie树,时间复杂度O(m*len),其中len表示敏感词平均长度,m 表示敏感词个数
- 构建失败指针,每个节点构建失败指针不会超过len次(树的平均高度),整个失败指针就是O(k*len), k 是节点个数
- 匹配复杂度
for循环依次遍历主串中每个字符,for循环内部的while复杂度O(len),总的复杂度O(n*len),敏感词不会很长,所以近似于O(n)
3. python包
https://pypi.org/project/ahocorasick-python/
https://pypi.org/project/ahocorasick-rs/
字符串匹配算法(AC自动机 Aho-Corasick)相关推荐
- 字符串匹配算法 -- AC自动机 基于Trie树的高效的敏感词过滤算法
文章目录 1. 算法背景 2. AC自动机实现原理 2.1 构建失败指针 2.2 依赖失败指针过滤敏感词 3. 复杂度及完整代码 1. 算法背景 之前介绍过单模式串匹配的高效算法:BM和KMP 以及 ...
- go regexp匹配字符串_多模式字符串匹配算法ac自动机(用go语言实现)
本文主要包括三部分内容 字典树 建立ac自动机 ac自动机匹配规则 字典树 字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种. 典型应用是用于统计,排序和保存大量的字符串(但不仅限 ...
- Aho-Corasick 多模式匹配算法(AC自动机) 的算法详解及具体实现
多模式匹配 多模式匹配就是有多个模式串P1,P2,P3-,Pm,求出所有这些模式串在连续文本T1-.n中的所有可能出现的位置. 例如:求出模式集合{"nihao","ha ...
- 字符串处理 —— AC 自动机
[概述] KMP 算法用于解决长文本的单模板匹配问题,字典树用于解决单个单词(短文本)多模板匹配问题,而 AC 自动机用于解决的是长文本的多模板匹配问题,其是以 trie 树的结构为基础,结合 KMP ...
- 字符串算法 | AC自动机算法
1.简介 一种多模式串匹配算法, 可以快速从主串中同时找出所有包含的所有模式串. 对比KMP是单模式匹配, 虽然可以使用单模式串匹配算法逐个进行查找模式串, 但是实际场景中,若模式串的数量可能很大,并 ...
- 字符串(AC自动机(fail tree))
传送门 注意:注释中的那段代码是不能用的 #include<iostream> #include<cstdio> #include<cstring> #includ ...
- 【算法无用系列】AC自动机敏感词过滤
简介: 本文是博主自身对AC自动机的原理的一些理解和看法,主要以举例的方式讲解,同时又配以相应的图片.代码实现部分也予以明确的注释,希望给大家不一样的感受.AC自动机主要用于多模式字符串的匹配,本质上 ...
- 提高篇 第二部分 字符串算法 第4章 AC自动机
https://blog.csdn.net/wangyh1008/article/details/81428056 [模板]AC自动机(加强版) 洛谷3796 AC自动机_A_loud_name-CS ...
- TypeScript:Aho–Corasick算法实现敏感词过滤
敏感词过滤应该是许多后端同事经常会遇到的需求,无论是评论.弹幕.文章,都需要做敏感词过滤处理来规避风险.在前端开发中,使用replace函数来替换字符串是我们的常规操作,在这之前我思考过如果用Java ...
- 模板 - AC自动机
ACM-ICPC模板 目录 求有多少个模式串在文本串里出现过 建fail树dfs求每个模式串在文本串中的出现次数 ac自动机fail树上dfs序建可持久化线段树 AC自动机是一种多模匹配算法 AC自动 ...
最新文章
- 【数据库】兴唐第二十七节课之jdbc的使用
- TIOBE 5 月编程语言榜单:Python 超越 Java 重回第二,Rust 崛起
- picACG本地缓存目录_7天用Go动手写/从零实现分布式缓存GeeCache
- 《C和指针》学习备忘
- 大疆口袋云台 最大存储卡_佳能云台相机专利曝光:可换镜头设计,将与大疆竞争...
- 2019了,转行学编程过时了吗?
- 指针01:指针的定义与使用
- 被替换的项目不是替换值长度的倍数_机器学习中处理缺失值的9种方法
- 有约束的最小二乘方图像复原方法_matlab图像复原算法
- 计算机软件研究方法与技术路线,毕业论文研究方法与技术路线
- Win11预览版更新错误怎么办?Win11预览版安装失败的解决方法
- openCV利用航拍相机从底部向上扫描物体拼接全景图
- python远程访问服务器获取文件
- 月是故乡明,每逢佳节倍思亲,近乡情更怯
- 软件工程——形式化方法概述
- 【单片机毕业设计】【mcuclub-jj-026】基于单片机的垃圾桶的设计
- 2019HDU多校第十场
- 拍照 识别 翻译 云脉慧眼
- JS之Web API
- 湖南文旅数据中心:湖南文旅数据早知道(9月10日)