title: 使用AC自動機解決文章匹配多個候選詞問題
abbrlink: bfa2c2fe
date: 2021-09-28 13:36:59
tags:
- 算法與數據結構
- AC自動機
categories: -
- 技術基礎
- 算法與數據結構
description: 'KMP算法用於單個字符串匹配,AC自動機用於文章中匹配多個候選詞。'
作者:Grey
原文地址: 使用AC自動機解決文章匹配多個候選詞問題
解決的問題
KMP算法用於單個字符串匹配,AC自動機用於文章中匹配多個候選詞。
流程
第一步,先將候選詞先建立前綴樹。
第二步,以寬度優先遍歷的方式把前綴樹的每個節點設置fail指針, 頭節點的fail指針指向空, 頭節點孩子的fail指針指向頭, 其他節點的fail指針設置邏輯為:來到X節點的時候,是設置X的孩子的fail指針。
case 1:
假設X通過b指向了它的孩子,假設孩子為C,X的fail指針指向的節點假設為Y,Y有走向b的路,且Y走向b的路是指向的Z,那么 C的fail指針指向Z,Y沒有走向b的路,那么就看Y的fail指針指向的節點的fail指針有沒有走向b的路,依次往復,如果走到null都沒有,那么進入case 2
case 2:
如果X的fail指針指向null,那么就把X的孩子C指向頭節點
候選詞構造AC自動機的一些示例,其中虛線表示節點fail指針的指向位置,黑色點表示候選詞結尾位置。
示例一 ["abc","bkf","abcd","bkc"]
示例二 ["abcde","cde","e"]
示例三 ["abcde","bcde","cde","de","e"]
示例四 ["abcdef","cdef","ex"]
示例五 ["abcde","bcdf","cdtks"]
示例六 ["abc","abcde","abcd","bc","cd"]
示例七 ["abck","bct","st"]
fail指針的含義
假設要以這個字符結尾,哪一個另外的后綴串和其前綴串完全相等
假設["abcde","bcde","cde","de","e"],所以abcde中e的fail指針指向bcde中的e,因為以abcde中的e的后綴有bcde和候選詞bcde的前綴匹配最長。
匹配規則
每次來到一個節點,根據fail指針轉一圈,如果有描黑的點(結尾點)就收集答案,同時把結尾標志為已處理(防止重復收集),匹配失敗的時候,要順着fail指針蹦到另外一條路徑上繼續匹配。
舉例
文章:"abcde"
候選詞:["abc","abcde","abcd","bc","cd"]
流程:
第一步,先對候選詞建立前綴樹並連接好fail指針,建立好以后,如下圖
第二步,文章的逐個位置進行匹配。來到第一個字符a
, 前綴樹中有走向a
字符方向的路。如下圖,走到2號點位置:
然后停在2號點位置,順着fail指針走一圈,如果有黑色點(結束點)就收集答案。所以,在2號點位置,順着fail指針走一圈分別要經過2號點,1號點,均不是結尾點,所以沒有答案收集。然后再匹配文章的下一個字符b
, 前綴樹來到如下3號位置節點:
然后停在3號節點,順着fail指針走一圈,分別會經歷7號節點和1號節點,均不是結尾點,所以未收集到答案。
繼續匹配文章下一個節點c
,前綴樹來到4號位置:
然后停在4號位置,順着fail指針走一圈,分別經歷了4號節點,8號節點,9號節點和1號節點,其中4號和8號是結尾點(表示abc的結尾和bc的結尾),所以收集到兩個答案abc
和bc
。
繼續匹配文章中的d字符,來到5號節點
然后停在5號節點上,順着fail指針走一圈,會經歷5,10,1號節點,5和10號節點分別是abcd
和cd
的結尾,所以收集到了abcd
和cd
兩個答案。
最后來到文章最后一個節點e,即到6號點位置
停在6號點位置,順着fail指針走,經過6號和1號,6號為abcde
的結尾,所有收集到了abcde
這個答案。