現在有兩個字串a和b,問你在a中是否有b,有幾個??
其實剛開始遇到這個問題的時候,我覺得挺簡單的呀!依次迴圈過去查詢不就可以了,
當然這樣做肯
定能實現,而且程式編寫簡單粗暴,兩個迴圈就解決了。但是這種方法的
時間複雜度是o(m*n),
m是字串a的大小,n是字串b的大小,這樣時間複雜度
就太高了,我們需要乙個時間複雜度低的
演算法,這樣kmp演算法就孕育而生了,演算法的時
間複雜度為o(m+n)。
演算法的第一步就是建立乙個next陣列,這個陣列有啥用,這個後面解釋。
next陣列表示的是字串b的前
綴和字尾最大相等的數量,這句話什麼意思??舉個例子吧。
假設a=「abaabaabbabaaabaabbabaab」
b="abaabbabaab"
對於前i個數,假設i=4,這字串「abaa」的字首是"a",「ab」,"aba";
字尾是"a","aa","baa",其中
字首和字尾相同的字串有一組,是「a」,所
以最大相同的字串字元數為1,故next[i-1=3]=1(數
組是從0開始計數,所
以這裡是i-1);根據這個規律我們可以寫出陣列b的next=;
演算法的第二步就是利用字串b對字串a逐步右移,在a中移動的位置用
j來表示,b中移動的位置
用k來表示,以上面例子來解釋這個演算法,當j=0,k=0
時,a字串的『a』和b字串的'a'兩個字元相
等,則j++;k++;j=1,k=1時,
a字串的『b』和b字串的'b'兩個字元相等,繼續j++,k++;依次類
推到i=5,j=5時
,a字串的『a』和b字串的'b'兩個字元不相等。這時候j=next[j-1]=2,繼續將a
陣列的第i個字串與b陣列的第j個字串相比較,此時a字串的i=5為『a』,b字元
串j=2(此時j的值已經發生了
改變)的值為『a』,兩個字串相同,則i++,j++;這時候a字串的陣列為'a',b字串的陣列為『a』,重
復上述過程。最後知道i的值與a字串長度相等的時候迴圈結束。這裡需要注意的一點是,當比較字元與
模板字元一直不相等,就比如假設上述例子i=5時遇到的字元不是'a',而是『c』,則j=2的字元也不相等,
則j=next[j-1]=0;當j=0時的字元也和『c』不相等,如果遇到這種情況不處理的話就會出現溢位的情況,所
以我們需要對其進行處理。當我們j=0時還是與第i個字元不相等時,我們就應該跳過這個字串,即i++;
在程式設計的時候這一點尤其要注意。
介紹完該演算法的整個過程,現在來分析一下它的可行性,以及為什麼用產生乙個next陣列??這個數
組有什麼作用??如果你不考慮演算法的層面,僅僅從數學層面上來做這道題目,我們肯定第1個字母進行比
較,然後在第6個字元的時候斷開了,然後你會立即從第4個字元開始進行比較,你這樣做的原理是字串
a第6個字元前面兩個字元與字串b的前兩個字元相同,所以我們選擇第4個字元開始,這時候你再想想next
陣列產生的原理,有沒有發現點什麼??
我們在第6個字元的地方斷的,說明a和b前5個字元相同,next[5-1](表示第5個數)表示字首和字尾最
大相同的字串數目,這時候是2。這說明b字串的第1和第2的字元肯定和a陣列中第4和第5個字元相等,
如果這樣的話我們只需要直接b陣列的第三個元素與a陣列的第6個元素比較就可以了。現在知道next陣列的
作用了吧!!!
下面是我對該演算法寫的c**,僅僅參考,有錯誤請指教:
#include"stdio.h"
#include"string.h"
#include"malloc.h"
#define n 20 //定義字串模板長度
#define n1 50 //定義需要匹配的字串的長度
int *get_array(char *b); //得到next陣列
void main()
else //如果有乙個字元一直找不到匹配,則進行下乙個字元重新匹配
} }if(flag) //判斷是否存在該模板字串
else
getchar();
}int *get_array(char *b)
}next[i]=max; //將最大數目的字首賦值給next陣列
} }return next;
}
字串查詢演算法kmp
字串查詢最簡單的方法就是乙個乙個地 滑動 查詢。這樣查詢演算法複雜度可定很高,假設pattern的長度為m,文字txt的長度為n,那麼演算法複雜度為o m n m 1 kmp模式搜尋演算法 kmp knuth morris pratt 我只認識knuth,大名鼎鼎的高納德老頭子嘛。kmp演算法的基本...
字串查詢演算法kmp
給定乙個文字串s,和乙個匹配串p,要求查詢p第一次在s中出現的位置。常見的方法如暴力搜素,逐個匹配s i p j 若匹配,下標後移。不匹配,i回溯到這次匹配前的下一位置,j置為0,重新匹配。最壞情況,時間複雜度o n m int violencesearch char s,char p else i...
字串查詢KMP演算法
如果你用過ctrl f這個快捷鍵,那麼你有很大的概率使用過這個演算法,這就是在待查詢字串 可能有成千上萬個字元 中找出模式串 比較小,可能有幾個字元 可能找到大於或者等於1次的位置。例如,在ababcd中找出abc。這裡介紹演算法思想,只給出了第一次出現的位置。void find char t,ch...