日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

敏感词屏蔽——AC自动机

發布時間:2024/5/14 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 敏感词屏蔽——AC自动机 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

個人微信公眾號:程序員宅急送

一、算法介紹

上一周我們講了Trie樹,這次的AC自動機是Trie樹的一個改進版,也是一個多模式串匹配算法。

區別在于Trie樹——在一堆模串中找尋符合條件的前綴(搜索引擎的關鍵詞彈出選項)

AC自動機——找尋符合條件的后綴。

二、算法講解

1、首先我們構建一個如圖的Trie樹

如下圖

2、在學習KMP算法的時候,我們說到了好前綴的前綴子串和后綴子串匹配。

在Trie樹中,我們借鑒這個思路,如果出現了不匹配字符,我們就去Trie樹中找“可匹配的最長后綴”。

在KMP算法中,我們又next數組,在Trie樹中,我們用”失敗指針“。

如下圖

三、代碼

AC自動機的關鍵在于兩個部分。1、構建Trie樹。2、構建失敗指針

#include <iostream> #include <vector> #include <string> #include <map> #include <queue> using namespace std; typedef struct _acNode {char data;struct _acNode* children[26] = {0};//此處我假設只有26個小寫字母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){//失敗指針發揮作用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; }

打印結果

index0 length = 3 index1 length = 2 請按任意鍵繼續. . .

總結

以上是生活随笔為你收集整理的敏感词屏蔽——AC自动机的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。