字符串匹配算法(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自动机
  1. 构建Trie树,时间复杂度O(m*len),其中len表示敏感词平均长度,m 表示敏感词个数
  2. 构建失败指针,每个节点构建失败指针不会超过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/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/480180.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习资源和记录

学习记录&#xff1a; 2019.08.01&#xff1a; 林轩田机器学习技法--Matrix Factorization &#xff1a;https://redstonewill.com/783/ [ 收获 ]&#xff1a;先假设 有用户特征向量&#xff08;维度为d表示用户对d种特性的不同喜爱程度&#xff09;、有电影特征&#xff08…

Redis系列教程(五):Redis哨兵、复制、集群的设计原理,以及区别

前一篇文章高并发架构系列&#xff1a;Redis为什么是单线程、及高并发快的3大原因详解谈了Redis高并发快的3个原因&#xff0c;本篇主要谈Redis的高可用&#xff0c;两篇合起来就可以把redis的高并发和高可用搞清楚了。 谈到Redis服务器的高可用&#xff0c;如何保证备份的机器…

老刘说NLP:焦虑被大肆贩卖下的自然语言处理学习思考

一、话题的由来 近期&#xff0c;有不少朋友来信&#xff0c;来询问如何看待自然语言处理这个方向&#xff0c;表示对当前的状态很不满&#xff0c;希望能够尽快地找到一个合适的方向、快速的学习方式&#xff0c;提升自己的自然语言处理能力&#xff0c;从而找到一个算法岗位的…

垃圾分类智能化-垃圾分类机器人

垃圾分类智能化-奇虎机器人&#xff1a; https://www.chatbot.cn/news-253.html 在人工智能眼里&#xff0c;垃圾分类分几步&#xff1f;&#xff1a;https://mp.weixin.qq.com/s/MlKnx77XGOUvZG1J-PtqMw 垃圾邮件分类之朴素贝叶斯算法实践&#xff1a;https://mp.weixin.qq.…

论文浅尝 | 区分概念和实例的知识图谱嵌入方法

链接&#xff1a;https://arxiv.org/pdf/1811.04588.pdf知识图谱的表示学习最近几年被广泛研究&#xff0c;表示学习的结果对知识图谱补全和信息抽取都有很大帮助。本文提出了一种新的区分概念和实例的知识图谱表示学习方法&#xff0c;将上下位关系与普通的关系做了区分&#…

写在校招季,谈谈机器学习岗的Offer选择问题

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | 吴海波 现在校招开始的越来越早&#xff0c;今年的实习生招聘还是异常火爆&#xff0c;简历一堆&#xff0c;而且是越来越没有区分度&#xff0c;以前面个xgboost的论文细节&#xff0c;就能区分很多人&…

leetcode--数组(Easy)

2019.08.02 1.返回和为指定值的两数的索引 基本思想&#xff1a;哈希表实现&#xff1a;把数组中的值作为key&#xff0c;索引作为value&#xff0c;在一此遍历的过程中&#xff0c;一边转map&#xff0c;一边查找符合要求的两个数 def twoSum(self, nums: List[int], target:…

Redis系列教程(六):Redis缓存和MySQL数据一致性方案详解

需求起因 在高并发的业务场景下&#xff0c;数据库大多数情况都是用户并发访问最薄弱的环节。所以&#xff0c;就需要使用redis做一个缓冲操作&#xff0c;让请求先访问到redis&#xff0c;而不是直接访问MySQL等数据库。 这个业务场景&#xff0c;主要是解决读数据从Redis缓存…

贪心算法(Greedy Algorithm)之霍夫曼编码

文章目录1. 贪心算法2. 应用2.1 找零钱2.2 区间覆盖2.3 霍夫曼编码霍夫曼编码完整代码1. 贪心算法 我们希望在一定的限制条件下&#xff0c;获得一个最优解每次都在当前的标准下做出当下最优决策&#xff08;整体不一定最优&#xff09;&#xff0c;做出的决策不可以后悔&…

技术思考:也谈知识图谱平台中的数据流程与构建范式思考

笔者之前写过一篇文章《关于知识图谱标准化构建平台的思考&#xff1a;知识图谱只能做项目&#xff0c;不能做平台&#xff1f;》&#xff0c;地址&#xff1a;https://blog.csdn.net/lhy2014/article/details/119857488&#xff0c;从技术实现的难度上&#xff0c;对这一平台的…

数据结构中基本查找算法总结

原文地址&#xff1a;https://www.cnblogs.com/xuzhp/p/4638937.html 基本查找算法 一、查找的基本概念 查找&#xff0c;也可称检索&#xff0c;是在大量的数据元素中找到某个特定的数据元素而进行的工作。查找是一种操作。 二、顺序查找 针对无序序列的一种最简单的查找方式…

领域应用 | 大众点评搜索基于知识图谱的深度学习排序实践

本文转载自公众号&#xff1a;美团技术团队。 本文介绍了大众点评搜索核心排序层模型的演化之路&#xff0c;包括结合知识图谱信息构建适合搜索场景的Listwise深度学习排序模型LambdaDNN以及特征工程实践和相关工具建设。1. 引言挑战与思路搜索是大众点评App上用户进行信息查…

KDD2020 | 揭秘Facebook搜索中的语义检索技术

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | 江城编 | 可盐可甜兔子酱导读&#xff1a;今天分享一下 Facebook 发表在 KDD2020 的一篇关于社交网络搜索中的 embedding 检索问题的工作&#xff0c;干货很多&#xff0c;推荐一读。论文题目&#xff1…

python下载网上的文件

1.使用 urlretrieve 最最最简单&#xff01;&#xff01;&#xff01;&#xff01; from urllib.request import urlretrieve # Python 2.7.9 之后版本引入了一个新特性&#xff1a;当你 urllib.urlopen一个 http s的时候会验证一次 SSL 证书 &#xff0c;当目标使用的是自签…

Redis系列教程(八):分布式锁的由来、及Redis分布式锁的实现详解

在很多场景中&#xff0c;我们为了保证数据的最终一致性&#xff0c;需要很多的技术方案来支持&#xff0c;比如分布式事务、分布式锁等。那具体什么是分布式锁&#xff0c;分布式锁应用在哪些业务场景、如何来实现分布式锁呢&#xff1f;今天来探讨分布式锁这个话题。 什么是…

平衡二叉树、二叉排序树-数据结构

数据结构之平衡二叉树建立&#xff1a;https://www.cnblogs.com/zhujunxxxxx/p/3348798.html 平衡二叉树&#xff08;AVL树&#xff09;及C语言实现&#xff1a;http://data.biancheng.net/view/59.html 二叉排序树与平衡二叉树的转化

技术交流:老刘说NLP技术公众号开通

我有一个念想&#xff1a;在当今PR文章满天飞的背景下&#xff0c;我们能够保持人间清醒&#xff0c;对NLP技术有客观、公正的了解&#xff0c;并实事求是地进行技术实践和知识共享。老刘说NLP&#xff0c;将定期发布更多、更简单、更有趣的语言知识、想法、笔记&#xff0c;包…

POJ 2453 贪心应用

文章目录1. 题目1.1 题目链接1.2 题目大意1.3 解题思路2. Accepted 代码1. 题目 1.1 题目链接 http://poj.org/problem?id2453 1.2 题目大意 一个数x的二进制表示有n个1&#xff0c;求一个有相同个数1的二进制数&#xff08;比x大&#xff0c;且要最小的&#xff09; 1.3…

leetcode--数组(Medium1)

2019.08.05 3.无重复字符的最长字串 基本思想&#xff1a;双指针、哈希表实现&#xff1a; 使用 head 指向无重复子串的头&#xff0c;ind 指向当前位置&#xff08;即当前无重复子串的尾&#xff09;&#xff0c;len_max记录当前无重复字串的最长长度&#xff0c;使用字典的 …

ICML2020 | 一行代码就能实现的测试集上分技巧

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | 苏剑林编 | 夕小瑶在训练模型的时候&#xff0c;我们需要损失函数一直训练到0吗&#xff1f;显然不用。一般来说&#xff0c;我们是用训练集来训练模型&#xff0c;但希望的是验证集的损失越小越好&…