kmp演算法**:
首先,字串「bbc abcdab abcdabcdabde」的第乙個字元與搜尋詞「abcdabd」的第乙個字元,進行比較。因為b與a不匹配,所以搜尋詞後移一位。
因為b與a不匹配,搜尋詞再往後移。
就這樣,直到字串有乙個字元,與搜尋詞的第乙個字元相同為止。
接著比較字串和搜尋詞的下乙個字元,還是相同。
直到字串有乙個字元,與搜尋詞對應的字元不相同為止。
逐位比較,直到發現c與d不匹配。於是,繼續將搜尋詞向後移動。
逐位比較,直到搜尋詞的最後一位,發現完全匹配,於是搜尋完成。
標號(j)01
2345
6模式串(ch)ab
cdab
d——就是回溯到存在「對稱」的地方。
從圖中可以分析得出,當掃瞄到模式串中某一位發現不匹配,總是回溯到在這一位之前的部分模式串存在重複的地方。
所以,next(j)就是當模式串第j位不匹配時即將要退回到的字母標號。
不管第一位和第二位是什麼,next(0)=-1,next(1)=0,這是固定的。
ps:模式串「abcdabd」,下標從0開始哦!
當j=1時,模式串ch[1]=「b」,「b」之前有「a」,不存在重複(0位),所以next[1]=0;
當j=2時,模式串ch[2]=「c」,「c」之前有「ab」,不存在重複(0位),所以next[2]=0;
當j=3時,模式串ch[3]=「d」,「d」之前有「abc」,不存在重複(0位),所以next[3]=0;
當j=4時,模式串ch[4]=「a」,「a」之前有「abcd」,不存在重複(0位),所以next[4]=0;
當j=5時,模式串ch[5]=「b」,「b」之前有「abcda」,存在重複「a」(1位),所以next[5]=1;
當j=6時,模式串ch[6]=「d」,「d」之前有「abcdab」,存在重複「ab」(2位),所以next[6]=2;
觀察第4位「a」,當它不匹配時,按照next[4]回溯到標號0也為字母「a」,這時再匹配「a」是徒勞的,因為已知「a」不匹配,所以就繼續退回到標號0字母「a」的next[0]=-1。為了計算更加直接,就有了nextval對next陣列的優化:
只看前面有重複字母的幾位就可以。
首先,nextval[0]預設為-1;
當1≤j≤3時,「bcd」在此之前均無重複的字母,所以nextval[j]=next[j];
當j=4時,模式串ch[4]=「a」,next[4]=0,ch[0]=「a」=ch[4],由於「a」=「a」,所以nextval[4]=nextval[0]=-1;
當j=5時,模式串ch[5]=「b」,next[5]=1,ch[1]=「b」=ch[5],由於「b」=「b」,所以nextval[5]=nextval[1]=0;
當j=6時,模式串ch[6]=「d」,next[6]=2,ch[2]=「c」=ch[6],由於「c」≠「d」,所以nextval[6]保持原樣,即nextval[6]=next[6]=2;
功能1:返回模式串ch在主串str中首次出現的位置,未出現輸出-1
功能2:返回模式串ch在主串str**現的次數
#include#define max 1000005using
namespace
std;
char
str[max],ch[max];
intnext[max],slen,clen;
void
getnext()}//
返回模式串ch在主串str中首次出現的位置
//返回的位置是從0開始的
intkmp()
else j=next[j];
}if(j==clen)
return i-clen;
else
return -1;}
//返回模式串ch在主串s**現的次數
intcount()
getnext();
for(i=0;i)
}return
sum;
}int
main()
return0;
}
KMP演算法(模板)
time limit 1000ms memory limit 65536k 有疑問?點這裡 給定兩個字串string1和string2,判斷string2是否為string1的子串。輸入包含多組資料,每組測試資料報含兩行,第一行代表string1 長度小於1000000 第二行代表string2 長...
KMP演算法模板
在文字t 1.n 中找到某個模式p 1.m 所有出現的位置被稱作字串匹配問題 m n p3375 模板 kmp字串匹配 這道題在洛谷上的評級居然是普及 普及?qvq 實現起來還是比較簡單的,只不過有很多細節可以有很多種寫法,看別人的 容易凌亂。理解起來比較困難的部分是如何get next 不建議初學...
kmp演算法模板
字串匹配樸素演算法 傳統的字串匹配 效率較低 計算主串中模式串出現的次數 include include using namespace std int index string s,string t else if j lent return count int main kmp演算法 下標從零開...