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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

深入理解Aho-Corasick自动机算法

發布時間:2025/3/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解Aho-Corasick自动机算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0.前言

? 我總是對那些具有狀態轉移過程的算法,心懷敬意。

? 例如:遞歸、遞推、動規、DAT 以及現在要說的 AC 自動機算法。

? 數學真是優美!

? ? ? ? ? ??? ? ? ? ? ??? ? ? ? ? ??? ? ?—— 致那些牛逼到不行的數學家們

?

1.版權說明

商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
本文作者:Q-WHai
發表日期: 2015年10月24日
本文鏈接:https://qwhai.blog.csdn.net/article/details/49335051
來源:CSDN
更多內容:分類 >> 算法與數學

?

2.概述

??Aho-Corasick automaton(后面心均以AC代替),該算法在1975年產生于貝爾實驗室,是著名的多模匹配算法之一。

??AC自動機算法分為3步:構造一棵Trie樹,構造失效指針和模式匹配過程。而這3步就是AC自動機算法的精髓所在,分別對應我們后面馬上要說的3個函數:success,failure和emits.

?

3.特別說明

3.0.學前導讀

? 在學習本文之前,需要兩個方面的知識背景。一個是Trie樹,一個是KMP算法。大家可以移步到兩面的兩個鏈接中,學習一下。之后,回過頭來再看我們的AC自動機,就可以會比較容易消化,也能更容易理解其中的精髓。

? 《數據結構:字典樹的基本使用》

? 《算法:模式匹配之KMP算法》

3.1.本文參考

? 《Aho-Corasick算法的Java實現與分析-碼農場》

?

4.一睹為快

? 以經典的ushers為例,模式串是he/ she/ his /hers,文本為“ushers”。構建的自動機如圖:

?

5.原理說明

5.0.算法比較

? 正如前面所說,AC算法是基于Trie樹且是KMP模式匹配算法的擴展。那么這里我們就可以從兩個方面來作為切入點,詳細說明一下AC算法或是AC自動機究竟是何物。

? 首先明白兩點:Trie樹的核心點是狀態轉移,KMP模式匹配的核心點是減少重復匹配。

? 先說Trie樹吧。在之前的博客中,我還是用了很多的篇幅來說Trie樹,不算這一篇的話,也有3篇文章或多或少都和Trie樹扯上點邊兒。前面的Trie樹中,每個節點既是字符本身,又是節點的狀態(DAT則不是這樣)。節點為字符本身,這個好理解,那又是節點的狀態這個要怎么解釋呢?因為我們知道,當我們在遍歷的過程中,走到某一個點的時候,比如說:目前有兩個字典字符串:T1:"abcde"和T2:"abdef",當我們在遍歷的過程中走了"abcd"且停在了'd'字符上.這個時候,我們可以認定目前是處于字符串T1上的。因為當前節點可以代表其狀態。而在T1和T2中,兩個'd'節點的狀態是不同的。而Trie樹的狀態轉移則可以理解為,我們在遍歷到節點d的時候,動態確定節點d的下一個狀態,即節點e。

? 再說說KMP模式匹配。在KMP模式匹配的過程中,我們使用到了一個next函數(如果你高興,也可以說這是一張next表)。next函數的作用是,當我們在匹配的過程中,發生了匹配失敗的時候,可以將模式串向前滑動n個字符,從而省去了n次的比較操作。而具體的操作方法及說明,我在之前的博客中也有介紹,這里不再詳細說明。

? 試想一下,如果我們要匹配一個文本文件d(舉例文件的目的是為了說明,這個匹配字符串可能會是一個很長的字符串),使用Trie樹的匹配方式,依然需要對d進行循環遍歷,就像樸素模式匹配那樣。Trie樹減少的只是在Trie樹中重合的部分,所以時間復雜會相當高。那么,KMP算法呢?對于KMP算法,我們要清楚一點。KMP算法是給模式串生成next函數,在多模式的情況下,我們需要生成很多的next函數,再對每個模式進行匹配。這顯然也并不理想。

??基于以上這兩點,我們的AC算法誕生了。

5.1.原理

? AC為了克服Trie樹中無效匹配和KMP算法需要一個一個去匹配,設計了一種新的算法。算法中需要維護三個函數,分別是:

? success:從一個狀態成功轉移到另一個狀態(有時也叫goto表或是success表)。

? failure:從一個狀態按照普通流程會匹配失敗,這時我們要通過failure函數來做狀態跳轉。

? emits:命中一個模式串(也稱為output表)。

? 從上面的狀態轉移圖中就可以看出來,整個節點+實線就是success函數;而虛線就是failure函數;紅色節點則是emits函數。

?

6.代碼實現過程及說明

6.0.整體實現過程流程圖

??

6.1.創建Trie樹

? 其實AC自動機是建立在Trie的基礎之上的,從上面的狀態轉移圖中就可以獲得這一信息。而在AC算法的3個函數中的success函數就是一種Trie樹。

?

/*** 構造一棵trie樹* * @param trieConfig*/public Trie(TrieConfig trieConfig) {this(trieConfig, true);}public Trie(TrieConfig trieConfig, boolean ascii) {this.trieConfig = trieConfig;if (ascii) {this.rootState = new AsciiState();} else {this.rootState = new UnicodeState();}}

?

6.2.success表的創建

? 從上面我們知道,success函數的功能就是構建一個棵Trie樹。關鍵是如何構建,因為這個Trie樹的構建和我們之前說的那并不完全相同。

? 在AC算法中,我們把Trie樹中的節點就直接稱為狀態(State).在創建狀態轉移表的過程中,則是利用了遞推的思想。我們在添加字典的過程中,其實是去計算當前字符對應的下一下狀態。詳細過程,請參見如下代碼:

?

/*** 轉移到下一個狀態** @param character 希望按此字符轉移* @param ignoreRootState 是否忽略根節點,如果是根節點自己調用則應該是true,否則為false* @return 轉移結果*/private State nextState(Character character, boolean ignoreRootState) {State nextState = this.success.get(character);if (!ignoreRootState && nextState == null && this.rootState != null) {nextState = this.rootState;}return nextState;}@Overridepublic State nextStateIgnoreRootState(Character character) {return nextState(character, true);}@Overridepublic State addState(Character character) {State nextState = nextStateIgnoreRootState(character);if (nextState == null) {nextState = new UnicodeState(this.depth + 1);this.success.put(character, nextState);}return nextState;}

?

6.3.failure表的創建

? failure表的創建是一個廣度優先搜索的過程。在這個過程中,我們通過不斷遍歷狀態Trie樹。詳細編碼過程如下:

?

/*** 建立failure表*/private void constructFailureStates() {Queue<State> queue = new LinkedBlockingDeque<State>();// 第一步,將深度為1的節點的failure設為根節點for (State depthOneState : this.rootState.getStates()) {depthOneState.setFailure(this.rootState);queue.add(depthOneState);}this.failureStatesConstructed = true;// 第二步,為深度 > 1 的節點建立failure表,這是一個bfswhile (!queue.isEmpty()) {State currentState = queue.remove();for (Character transition : currentState.getTransitions()) {State targetState = currentState.nextState(transition);queue.add(targetState);State traceFailureState = currentState.failure();while (traceFailureState.nextState(transition) == null) {traceFailureState = traceFailureState.failure();}State newFailureState = traceFailureState.nextState(transition);targetState.setFailure(newFailureState);targetState.addEmit(newFailureState.emit());}}}

?

6.4.emits命中(output表的創建)

? 關于output表的創建,其實跟Trie樹中的結束結點標志很類似。都是在模式串的末尾對狀態進行修改的過程。而output表則是在狀態節點對象中以組合的方式來體現。

?

/*** 添加一個模式串* * @param keyword*/public void addKeyword(String keyword) {...currentState.addEmit(keyword);}/*** 添加一個匹配到的模式串(這個狀態對應著這個模式串)** @param keyword*/public void addEmit(String keyword) {if (this.emits == null) {this.emits = new TreeSet<String>();}this.emits.add(keyword);}

?

7.GitHub 源碼

https://github.com/qwhai/jac-core

?

8.征集

如果你也需要使用ProcessOn這款在線繪圖工具,可以使用如下邀請鏈接進行注冊:
https://www.processon.com/i/56205c2ee4b0f6ed10838a6d

總結

以上是生活随笔為你收集整理的深入理解Aho-Corasick自动机算法的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 免费看黄网站在线观看 | 欧美第一色 | 特种兵之深入敌后 | 九色porny蝌蚪视频 | av色图在线 | 伊人五月综合 | 中文字幕av亚洲精品一部二部 | xxx日韩 | 99视频国产精品免费观看a | 午夜神马影院 | 亚洲无毛视频 | 久久精品国产久精国产 | 亚洲每日在线 | 五月天av网站 | 精品色图 | 亚洲天堂av一区二区三区 | 欧美综合在线一区 | 秋霞网av| 国产乱子视频 | 久久精品美女 | 色奇米| 9色av| 国产精品 欧美 日韩 | 在线观看视频一区二区 | 亚洲大片免费观看 | 欧美日韩不卡一区二区三区 | 少妇裸体淫交视频免费看高清 | 岛国av一区 | av在线有码 | 天天弄天天干 | 爱看av在线 | 日批在线| 五月天婷婷丁香花 | 亚洲 欧美 另类 综合 偷拍 | 亚洲福利专区 | 欧美成人一区二区在线 | 日韩美女免费线视频 | 亚洲最大在线观看 | 啪啪一区二区 | 日韩精品v | 少妇人妻偷人精品一区二区 | 亚洲性视频 | 国产精品久久久久不卡 | 中文字幕日韩在线视频 | 亚洲欧美日韩色 | 白浆一区 | 极品少妇一区二区三区 | 色男人av| 亚洲欧美高清 | 精品天堂 | 成人午夜久久 | 久国产精品 | 又色又爽又黄gif动态图 | 99久久精品国产色欲 | 91av视频网| 亚洲另类自拍 | 日本在线视频一区二区三区 | 泰坦尼克号3小时49分的观看方法 | 五月婷婷av| 日韩一二三四 | 荫蒂被男人添免费视频 | 国产精品免费一区二区三区 | 国产人妻一区二区 | www.黄色小说.com | 日韩深夜在线 | 伦理亚洲 | 国产小视频免费在线观看 | 在线观看亚洲国产 | 中文字幕乱码中文字幕 | 人人爱人人插 | 在线看黄色的网站 | 国产成人精品午夜福利Av免费 | 色综合91 | 97精品国产97久久久久久粉红 | 日日操狠狠操 | 色吧综合 | 国产精品精品久久久 | av片网| 天堂一区二区三区四区 | 欧美在线日韩 | 国产在线视频导航 | 国产传媒视频在线观看 | 日本va欧美va精品发布 | 国产精品100| www.一区二区三区 | 久久久精品久久久久 | 69**夜色精品国产69乱 | 亚洲国产日韩欧美一区二区三区 | 三上悠亚一区二区 | 在线播放成人 | 成年人免费网站在线观看 | 少妇太爽了太深了太硬了 | 欧美123| 一区二区导航 | 亚洲激情中文字幕 | 久久中文娱乐网 | 亚洲av综合色区无码一区爱av | 丰满少妇一区二区三区视频 | 涩涩的视频在线观看 |