KMP演算法 字串匹配問題

2021-09-19 07:18:03 字數 2144 閱讀 6416

給定倆個字串str和match,長度分別為n和m。實現乙個演算法,如果字串str中含有字串match,則返回match在str中的開始位置,不含有則返回-1;

str="acbc",match="bc",返回2.

str="acbc",match="bcc",返回-1.

我們知道在match中a區域與b區域是匹配的,所以下次匹配只需要將match[k]和str[j]進行比較即可。之後一直進行這樣的滑動匹配過程,直到在str的某乙個位置把match完全匹配完,就說明str中有match。如果滑動到最後也沒有匹配出來,就說明str中沒有match。

驗證匹配演算法的正確性:

1,上述中,為什麼要直接讓match[k]和str[j]直接比較????

如上圖,假設匹配到a字元和b字元才發生了不匹配,所以c區域必然等於b區域,又因為我們知道nextarr的定義,所以我們也知道b區域也等於a區域,那麼我們就可以直接將match右滑動到如圖所示的位置,直接讓c字元和a字元比較。

2,為什麼a區域和b區域之間肯定匹配不了match呢???

我們用假設法:假設bb區域開始位置是不用檢查的其中乙個位置,如果從這個位置可以匹配出match部分子串,那麼,從match[0]開始也必然存在和bb區域相等的區域aa可以匹配出match部分子串。同時我們注意到aa比a區域大,bb比b區域大,我們找到了比b和a更大的字首和字尾子串。這個結論和求nextarr的值是相互矛盾的。

匹配過程分析完畢:match一直向右滑動,最壞的時間複雜度為o(n).

**:

int getindexof(const char *strcontent, const char *match)

int si = 0;

int mi = 0;

int tmp = new int[strlen(match)];

getnextarray(match,tmp);

while (si < strlen(strcontent) && mi < strlen(match))

else if (next[mi] == -1)

else

}free(next);

if(next != null)

next = null;

return mi == strlen(match) ? si - mi : -1;

}

最後一步求得nextarr陣列:1,對於match[0]而言,它前面沒有字元,所以nextarr[0]規定為-1.對於match[1]來說,在它之前只有match[0],但是nextarr的定義是要求任何子串的字尾不包括第乙個match[0],故nextarr[1]==0.

2,之後的nextarr陣列的值求解過程如下:

int pos = 2;//從下標2開始

int cn = 0;//

while (pos < length)

else if (cn > 0)

else}}

整個kmp演算法的複雜度為o(m)(求解nextarr陣列的過程)+o(n)(匹配的過程),因為有n>=m所以時間複雜度為o(n).

字串匹配問題 KMP匹配演算法

基本思想 字串匹配問題 在文字串中尋找是否有與模式串相同的子串 在字串匹配時,暴力匹配忽略了如果模式串開頭與中間有重複部分,在將模式串的後面的重複部分匹配後,無法繼續匹配的話,此時將模式串開頭實際上也已經被匹配了,可以直接從開頭重複部分之後開始匹配 這裡引入了乙個部分匹配值表,每個與模式串的字元對應...

字串匹配問題 KMP演算法

kmp演算法 kmp是解字串匹配這類題目的演算法,又稱 看毛片 演算法。如下圖,給定乙個長度為n的文字,給定乙個長度為m 的字串,求該字串在給定文字的中出現的次數。kmp就是解決這一類題目的。i 1 zzkzzzkzzzkzkkkz zzkzzkzzkzzk j 1繼續考慮上面的問題。首先我相信每個...

字串匹配問題 KMP演算法

字串匹配問題 給定兩個字串s 主串 和t 模式串 假設n strlen s strlen t m,判斷主串s中是否包含模式t,且返回t在s中所在的起始位置。這裡為簡單起見,若s包含t,則只返回第乙個t所在的位置。一般的蠻力法如下 蠻力法在遇到不匹配時,j每次都要回到t的起點,從新開始匹配,這樣來看效...