當有一段已知足夠長的字串t以及一段相對而言較小的字串p,而問題是要讓你統計p在t中出現的次數或者位置等這類匹配的問題。由於樸素匹配的時間複雜度不足以解決該問題時,可以嘗試用kmp匹配演算法。
我們發現樸素匹配演算法之所以複雜度高,是因為做了許多不必要的回溯查詢,而這些回溯過程,如果有存在迴圈節,則直接從迴圈節的對稱點開始匹配,這樣就把一些不必要的回溯跳過了。而這些不必要的匹配必須要用乙個next陣列記錄,而每個元素的含義時匹配串到當前長度的字串的字首和字尾相同的最大長度。規定字首長度為1的字串next = 0.
求next陣列
右偏移一位,和匹配串相同大小的next值捨去,next[0]=-1
kmp搜尋
寫法1:
#include #include #include /**
* ababcabaa
* a 0
* a b 0
* a b a 1
* a b a b 2
* a b a b c 0
* a b a b c a 1
* a b a b c a b 2
* a b a b c a b a 3
* a b a b c a b a a 1
*/int prefix[10000]; //next
char pattern[10001]=;
char str[1000001];
//得到字首表陣列
void get_prefix_table (char pattern, int next, int n) else else }}
}void move_prefix_table (int next, int n)
next[0] = -1;
}void kmp_search (char text, char pattern)
printf("}\n");
int i = 0;
int j = 0;
while(i < n)
if(text[i] == pattern[j]) else }}
free(prefix);
}int main()
寫法2:#include #include #include /**
* ababcabaa
* a 0
* a b 0
* a b a 1
* a b a b 2
* a b a b c 0
* a b a b c a 1
* a b a b c a b 2
* a b a b c a b a 3
* a b a b c a b a a 1
*/int prefix[10001]; //next
char pattern[10001]=;
char str[1000001];
//得到字首表陣列
void get_prefix_table (char pattern, int next, int n) else
}}void kmp_search (char text, char pattern) else
if(j == m) //匹配成功,根據情況更改條件,以及內部操作,注意時prefix[j-1]而不是prefix[j]!避免越界
}}int main()
單模式字串匹配演算法KMP
kmp演算法 2int kmp char s,file file,int pos 3 else 否則,下標指向當前字元的前乙個匹配項 12i next i 13if i 1 17 18 if s i 0 else 否則返回 1 22 return 1 23 獲得模式串的next陣列演算法 演算法中c...
kmp字串匹配
首先要對模式串進行預處理。預處理過程就是計算出指定位置的字首和字尾的最大相同的長度 啊啊啊啊。估計只有我乙個人能看懂 這個文章說得很清楚 比如說 a a a c b c a a a 0 1 2 0 0 0 1 2 3 void getnext int next,char par 20 int n 翻...
字串匹配 KMP
參考 從頭到尾徹底理解kmp 在字串 str 中 匹配模式串 pattern 1.計算模式串的 next 陣列 2.在字串中匹配模式串 當乙個字元匹配時,str i pattern k 繼續匹配下乙個字元 當當前字元不匹配時,根據 next 陣列移動模式字串,k next k next 陣列 描述模...