KMP演算法查詢相同字串

2021-08-08 04:38:41 字數 2227 閱讀 9865

現在有兩個字串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...