AC自動機入門,洛谷P3808

2021-09-23 15:41:57 字數 2630 閱讀 6740

給定n個模式串和1個文字串,求有多少個模式串在文字串裡出現過。

輸入輸出格式

輸入格式:

第一行乙個n,表示模式串個數;

下面n行每行乙個模式串;

下面一行乙個文字串。

輸出格式:

乙個數表示答案

輸入輸出樣例

輸入樣例#1:

2aaa

aa

輸出樣例#1:

兩個會出現在模板題面裡的詞語

文字串和模式串:

給你幾個單詞和乙個字串;

求在字串**現的單詞的個數

這裡文字串就是給的字串,模式串就是單詞。

ac自動機是乙個多模匹配演算法。

學習ac自動機要知道trie字典樹和kmp演算法。

知道trie和kmp的話ac自動機的演算法基本上也就會了

我覺著學ac自動機不是特別理解kmp演算法也行來著

然後我們先簡單說一下這兩個小東西

trie樹(字典樹),顧名思義,就是一顆樹。

那麼這顆樹用途就像字典一樣,用來儲存,統計,查詢字串(一般),

它工作原理就和英語字典一樣,通過公共字首儲存字串(公共字首就是在幾個字串中,前幾個相同的字元,比如solve ,solo,這兩個字元的公共字首就是so。)查詢字串;

對於乙個模式串s,s[i … s.size() - 1], i為樹的層數,在每一層我們查詢該層中是否有字母與該字元的字母相同,如果有直接找該字母的子節點,如果沒有,就新建乙個節點,標記為s[i];

同時在每個模式串最後乙個字母節點上做乙個標記(讓標記加一),表示是單詞的結尾這樣查詢時每遍歷到乙個就讓個數加上標記數。

fail指標其實就是kmp演算法在ac自動機裡的應用,我的理解就是乙個回溯查詢,比如在翻字典查乙個單詞(比如computer)時你記錯了翻到了字首是comm的這頁,這時你肯定不是回到c重新去找字首為c什麼的單詞而是回到com找字首為com什麼的單詞。

fail指標就是告訴你你沒找這個單詞找失敗的時候還可以去嘗試找那些類似的單詞,減少你重複從字首開始遍歷的過程。

我懶得用途片詳解過程

指標並不一定要指標實現,我們也可以用陣列。

第一層的指標全指向根節點(根節點為0不表示字母)

然後我們只要記住一句話,就可以掌握fail指標建立的精髓, 就是:

指標指向, 父親節點的fail指標 >>> 指向節點的 >>> 與該節點表示字母相同的》 子節點,若沒有,則指向根節點

聽起來有點繞我用字元斷了一下句,

畫的有丶醜。。。

我才不會說這就是我為什麼懶得用詳解的原因

我們可以看一下,下面這個圖有點撈前三個毋庸置疑時指向根節點的,然後我們再找第四層的子節點,從e開始,e父親節點為t那麼就看t的指標指的節點,t的fail指標指向了根節點,我們再遍歷根節點的子節點(只有乙個來著)發現是e,和我們原節點表示字母相同,於是我們就讓第四層e的fail指標指向第一層的e;

其他的都是同理得(因為畫的時候沒有好好想所以剩下的指的都是根節點-_-||)

;//單詞結尾的標記

int f[maxn]

;//fail指標

int cnt =0;

int n;

string s;

void

insert

(string s)

root = trie[root]

[nt]

;// printf("%d\n", root);

} cd[root]++;

//結尾時標記個數加一

}void

fail()

}while

(!q.

empty()

)else trie[x]

[i]= trie[f[x]

][i]

;//如果這個點沒有建點,就讓該節點為父親指標指向節點的子節點}}

}int

q(string s)

}return ans;

}int

main()

f[0]

=0;fail()

; cin >> s;

printf

("%d\n",q

(s))

;// for(int i = 1; i <= n; ++i)

// }

return0;

}指標版的ac自動機

陣列版的ac自動機

yyb大佬的部落格

講的都比我好,我就是看這個學的

kmp演算法

trie樹

洛谷P3808 模版 AC自動機(簡單版)

題目背景 這是一道簡單的ac自動機模版題。用於檢測正確性以及演算法常數。為了防止卡oj,在保證正確的基礎上只有兩組資料,請不要惡意提交。題目描述 給定n個模式串和1個文字串,求有多少個模式串在文字串裡出現過。輸入輸出格式 輸入格式 第一行乙個n,表示模式串個數 下面n行每行乙個模式串 下面一行乙個文...

洛谷P3808 模板 AC自動機(簡單版)

這是一道簡單的ac自動機模板題。用於檢測正確性以及演算法常數。為了防止卡oj,在保證正確的基礎上只有兩組資料,請不要惡意提交。給定n個模式串和1個文字串,求有多少個模式串在文字串裡出現過。輸入格式 第一行乙個n,表示模式串個數 下面n行每行乙個模式串 下面一行乙個文字串。輸出格式 乙個數表示答案 輸...

洛谷P3808 模板 AC自動機(簡單版)

給定n個模式串和1個文字串,求有多少個模式串在文字串裡出現過。輸入格式 第一行乙個n,表示模式串個數 下面n行每行乙個模式串 下面一行乙個文字串。輸出格式 乙個數表示答案 include using namespace std int const n 1000005 int const m 1000...