講乙個簡單的例子
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()void
insertt(node*root,char
*
s) p->num=1;}void
build_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的陣列。換言說,可存的元素型別越多,單個節點占用記憶體越大。如果用字典樹儲存漢字,那麼每個節點必須為數千個常用漢字開闢乙個陣列作...