字典樹 kmp ac自動機

2021-06-21 04:16:59 字數 2068 閱讀 2392

講乙個簡單的例子

ababcbababacba 裡面是否包含 bababac

根據我記得最裸的寫法是 o(nm)的bf演算法 。就是逐個匹配,但是時間非常的浪費。所以有了這kmp。

kmp 是針對 模式串 進行預處理過 來達到速度提公升。

a bab c bababacba 

bab a bac  

此時我們匹配到了這一步發現 a c 並不匹配,於是進入下個乙個匹配 而如果我們知道 a 失配了 就會跳到 上次與之前相配的字首去 變成了

aba bc  bababacba 

ba  babac  

我們可以觀察一下bababac ,如果有乙個字串 和 他 匹配到 baba 了 那麼代表了 當前下乙個字元是 a 是不匹配的 而接下來的 是 ba 是可以匹配的 

ababc baba bacba 

baba bac

那麼最好的策略是從跳到下個配點去的,這樣子就能節省時間。

而我們會建立乙個next的陣列 他的每一位(個人理解)是指向之前和他相鄰 最長的與模式字串字首(不包含自己)相等的長度。

#define max 100010

int next[max]; //預處理陣列

void kmp(char *s)

else

j=next[j];

}}//自我匹配

bool match(char *s1,char *s2)

else

j=next[j]; //回溯上次最佳位置

if(s2[j]=='\0')

return true; //匹配成功

}return false;

}接下來是字典樹,我感覺比較簡單,所以我打算寫少一點。

根據字典樹,我們可以很快的查詢一些字串。

假設我們 要查乙個單詞,我必須根據每乙個字母的前乙個字母逐步下向下查詢。字典樹也是一樣道理,

首先我們建立一棵樹,從乙個 根節點,根據字串,我們開始向下遍歷就可以了。

struct node

}; //節點

void build(node,*root,char *s)

p->val++;

}//建樹

bool node_search(node *root,char *s)

if(p->val==0)

return false;

return true;

}//查詢

ac自動機 我第一次接觸是為了 解決某一類問題的 即乙個字串中有包含了多少的模式串,即解決多串匹配問題。
同樣我們 要構造一顆字典樹。不過這顆字典樹與一般的不同,他需要包含乙個fail的指標。而這個指標有何用處呢?這也是ac自動機的精妙之處。fail指標,當時對於我通俗的來說是乙個字串的位置上 指向某乙個字串上的乙個位置,而這個位置到自身根節點(即這個字串的字首)是與當前節點之前的某一段是匹配的。

這樣我們就能知道字串之間的匹配和相容的程度。

接下來這張是網上通用的解釋
接下來,就開始實現**構造。
structnode;

node data[125];node*newnode()

voidinsertt(node*root,

char

*s)

p->num=1;

}voidbuild_ac(node*root)

else

} }

}}

KMP,擴充套件KMP,AC自動機總結 模板

為了方便統一,本文中下標均從0開始 kmp p3375 模板 kmp字串匹配 對於兩個字串s1,s2 s1 s2 求s2在s1中的出現位置 例如s1 ababa,s2 aba 在這個樣例中答案就是0 2 首先考慮暴力做法,對於s1的每乙個字元,我們都一該字元開始往後與s2對比.時間複雜度為 o n ...

AC自動機(KMP 字典樹)

ac自動機 kmp 字典樹 題目 輸入n個串,判斷有多少個搜尋串的子串 in out 1 47a ababc abcd abcde abcdef abcdefg abcd includeusing namespace std char str 1000000 100 struct node root...

字典樹問題與AC自動機

利用字串的公共字首來避免無謂的字串比較,降低查詢時間。字典樹節點 每個節點對應乙個最大可儲存字元陣列。假設字典只存26個小寫英文本母,那麼每個節點下應該有乙個長度為最大26的陣列。換言說,可存的元素型別越多,單個節點占用記憶體越大。如果用字典樹儲存漢字,那麼每個節點必須為數千個常用漢字開闢乙個陣列作...