敏感词屏蔽——AC自动机
生活随笔
收集整理的這篇文章主要介紹了
敏感词屏蔽——AC自动机
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
個(gè)人微信公眾號:程序員宅急送
一、算法介紹
上一周我們講了Trie樹,這次的AC自動(dòng)機(jī)是Trie樹的一個(gè)改進(jìn)版,也是一個(gè)多模式串匹配算法。
區(qū)別在于Trie樹——在一堆模串中找尋符合條件的前綴(搜索引擎的關(guān)鍵詞彈出選項(xiàng))
AC自動(dòng)機(jī)——找尋符合條件的后綴。
二、算法講解
1、首先我們構(gòu)建一個(gè)如圖的Trie樹
如下圖
2、在學(xué)習(xí)KMP算法的時(shí)候,我們說到了好前綴的前綴子串和后綴子串匹配。
在Trie樹中,我們借鑒這個(gè)思路,如果出現(xiàn)了不匹配字符,我們就去Trie樹中找“可匹配的最長后綴”。
在KMP算法中,我們又next數(shù)組,在Trie樹中,我們用”失敗指針“。
如下圖
三、代碼
AC自動(dòng)機(jī)的關(guān)鍵在于兩個(gè)部分。1、構(gòu)建Trie樹。2、構(gòu)建失敗指針
#include <iostream> #include <vector> #include <string> #include <map> #include <queue> using namespace std; typedef struct _acNode {char data;struct _acNode* children[26] = {0};//此處我假設(shè)只有26個(gè)小寫字母struct _acNode* fail = nullptr;bool isEnding = false;int index = 0; }acNode; class acAutoMachine { public:acAutoMachine(){root = new acNode;root->data = '/';root->fail = root;}void createTrie(string src){int srcLen = src.size();acNode* curPoint = root;for (int i = 0; i < srcLen; ++i){char curCh = src[i];int index = curCh - 'a';if (curPoint->children[index] == 0){curPoint->children[index] = new acNode;curPoint->children[index]->data = curCh;curPoint->children[index]->index = i;curPoint = curPoint->children[index];}else{curPoint = curPoint->children[index];}}curPoint->isEnding = true;}void buildFailPoint(){queue<acNode*> acNodeQueue;acNodeQueue.push(root);while (!acNodeQueue.empty()){acNode* p= acNodeQueue.front();acNodeQueue.pop();for (int i = 0; i < 26; ++i){acNode* pc = p->children[i];if (pc == 0) continue;if (p == root){//這里注意一下,是pc->fail = rootpc->fail = root;}else{acNode* q = p->fail;while (q != 0){acNode* qc = q->children[pc->data - 'a'];//這里寫q->children[i]也是可以的if (qc != 0){pc->fail = qc;break;}else if (qc == 0&&q == root){pc->fail = root;break;}q = q->fail;}if (q == nullptr){pc->fail == root;}}acNodeQueue.push(pc);}}}void match(string src) {int srcLen = src.size();acNode* p = root;for (int i = 0;i<srcLen;++i){int index = src[i] - 'a';while (p->children[index] == nullptr && p != root){//失敗指針發(fā)揮作用p = p->fail;}p = p->children[index];//沒有匹配的從root開始,if (p == nullptr)p = root;acNode* tmp = p;while (tmp != root){if (tmp->isEnding == true){int pos = i - tmp->index;cout << "index" << pos << " length = "<< tmp->index+1 << endl;}tmp = tmp->fail;}}} private:acNode* root;}; int main() {acAutoMachine ac;ac.createTrie("msb");//ac.createTrie("cb");ac.createTrie("sb");ac.buildFailPoint();ac.match("msbde");system("pause");return 0; }打印結(jié)果
index0 length = 3 index1 length = 2 請按任意鍵繼續(xù). . .總結(jié)
以上是生活随笔為你收集整理的敏感词屏蔽——AC自动机的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何调试正在运行的python程序_如何
- 下一篇: 小实验:关于期望的乘法性质