AC自動機之初學習

2021-06-22 23:48:07 字數 2750 閱讀 8890

昨天開始搞ac自動機,其實搞完kmp和trie樹之後搞ac自動機還是很簡單的,主要是形成一套ac自動機的**風格比較艱難,找了份簡潔明瞭實用性強的**分析了一天,以後就按這個風格寫了。

hdu2896

模板題,藉此把我加注釋的模板貼出來~

#include #include #include #include using namespace std;

int next[100001][128]; //trie樹

int fail[100001]; //失敗指標,相當於kmp的next陣列

int mark[100001]; //標記陣列,記錄節點資訊

bool used[501];

int ans;

int root,sum;

int n,m;

int newnode() //產生新的節點

void init() //初始化

void insert(char * s,int id) //構造trie樹

}while (!mq.empty())}}

/*這樣形成next構成乙個閉合的圖,對每個節點的所有孩子節點都能出發,要麼走到其真正孩子節點,要麼其沒有這個孩子,相當

於失配,走到失配後來到的位置,如果走到根節點還失配,則形成迴圈,看著是一條鏈,其實由於每次都是記錄的之前的資訊,記錄

之後尋找下乙個位置的花費是1,可以畫出這個bfs遞推過程體會一下

這樣形成的fail就是正常的fail指標了,即當前節點匹配下一節點失敗時要去的節點,由於這裡面跟next聯絡到一起,他們相互作用,使得

任意一次查詢的花費都是1,畫圖體會下一條鏈是怎樣形成的是最好的理解方式

*/}void query(char * s,int id)

for (int i=0;i<=len;i++)}}

}void dp()}}

}double ans=0;

//走到m步仍然沒有匹配成功的結果加起來便是不能匹配成功的概率,所有能匹配成功的結果

//都沒繼續遞推,所以走到m的時候沒有匹配成功便代表一直沒有匹配成功

for (int i=0;i>n>>m&&n+m)

scanf("%s",ch+1);

next[0]=next[1]=0;

getnext();

dp();

}}

ac自動機版:求出所有滿足題意的結果,相加#include #include #include #include using namespace std;

int next[1010][26];

int fail[1010];

int sum,root;

int n,m;

double dp[1010][15]; //當前步數為i,匹配的節點編號為j(其實根節點是0,其餘節點依次類推,自動機只有一條鏈,故也能理解為匹配長度)

double p[26];

char ch[15];

int newnode()

void init()

void insert(char * s)

}while (!mq.empty())}}

}int main()

init();

scanf("%s",ch);

insert(ch);

build();

int len=strlen(ch);

dp[0][0]=1; //第0步走到根節點的概率為1

for (int i=0;i

hdu2457

又是一道ac自動機加dp的題目,花了一晚上時間才寫出來,還是不熟悉用ac自動機完成樹形dp。。。

這道題讓求改變某些點使得不含病毒串的最少改變步數,那麼對目標串進行dp,對於目標串上的每個節點都有兩種選擇,要麼改變要麼不改變,然後,對每一步,列舉所有節點,從這個節點出發到其子節點作為待更新節點,看從這個節點出發能否使得下一步到待更新節點代表的狀態更優,如果待更新節點和當前步數匹配的節點相同,則表示不改變這個節點,不同則表示改變這個節點花費加1,然後看步數為len時在哪個狀態花費最小,輸出即可。

附**:

#include #include #include #include #include #include using namespace std;

int next[1010][4];

int fail[1010];

int mark[1010];

int sum,root;

map mp;

int n,m;

char ch[1010];

int dp[1010][1010]; //當前匹配的長度為i,處於t狀態,注意只需要匹配長度為len即匹配完成,由於值能變,所以在哪個位置不重要

const int inf=0x3f3f3f3f;

int newnode()

void init()

void insert(char * s)

}while (!mq.empty())}}

}int min(int a,int b)

void solve(char * s,int ca)

int main()

{ mp['a']=0;

mp['g']=1;

mp['c']=2;

mp['t']=3;

int ca=1;

while (cin>>n&&n)

{init();

for (int i=0;i

AC自動機 建立nlogn個AC自動機

string set queries 題意 給你3種操作,1 加入乙個串到集合中。2 刪除集合中的某乙個串 3 查詢集合中的字串在給定的字串種出現幾次。同乙個串可重複 解法 建立多個ac自動機,用二進位制分組來處理。加入給你21個串 分為 16 4 1,再新增乙個串的時候,即21 1,22 16 4...

AC自動機 學習筆記

是一種數學模型,大概就是由一堆狀態和狀態轉移規則等東西構成,能與外界交換資訊,並改變動作。這個是理論上的東西,了解就行,對ac自動機的理解沒有大影響。通俗的講就是在trie上做kmp,處理多模式串匹配問題。trie 的每個結點就是乙個狀態,根結點是初始狀態。ac自動機的行為被定義為一下3個函式 1....

AC自動機學習小記

ac自動機,aho corasick automaton,該演算法在1975年產生於貝爾實驗室,是著名的多模匹配演算法。其實ac自動機就是tire加上kmp。乙個簡單的問題 hdu2222 給出多個模式串,在給出乙個文字串,問模式串在文字串中出現了多少次。最簡單的做法就是將模式串加入的tire中,在...