KMP演算法 1 暴力匹配演算法

2021-07-22 05:41:28 字數 1605 閱讀 1491

假設現在我們面臨這樣乙個問題:有乙個文字串s,和乙個模式串p,現在要查詢p在s中的位置,怎麼查詢呢?

如果用暴力匹配的思路,並假設現在文字串s匹配到 i 位置,模式串p匹配到 j 位置,則有:

如果當前字元匹配成功(即s[i] == p[j]),則i++,j++,繼續匹配下乙個字元;

如果失配(即s[i]! = p[j]),令i = i - (j - 1),j = 0。相當於每次匹配失敗時,i 回溯,j 被置為0。

理清楚了暴力匹配演算法的流程及內在的邏輯,咱們可以寫出暴力匹配的**,如下:

int violentmatch(char* s, char* p)  

else

} //匹配成功,返回模式串p在文字串s中的位置,否則返回-1

if (j == plen)

return i - j;

else

return -1;

}

舉個例子,如果給定文字串s「bbc abcdab abcdabcdabde」,和模式串p「abcdabd」,現在要拿模式串p去跟文字串s匹配,整個過程如下所示:

1. s[0]為b,p[0]為a,不匹配,執行第②條指令:「如果失配(即s[i]! = p[j]),令i = i - (j - 1),j = 0」,s[1]跟p[0]匹配,相當於模式串要往右移動一位(i=1,j=0)

2. s[1]跟p[0]還是不匹配,繼續執行第②條指令:「如果失配(即s[i]! = p[j]),令i = i - (j - 1),j = 0」,s[2]跟p[0]匹配(i=2,j=0),從而模式串不斷的向右移動一位(不斷的執行「令i = i - (j - 1),j = 0」,i從2變到4,j一直為0)

3. 直到s[4]跟p[0]匹配成功(i=4,j=0),此時按照上面的暴力匹配演算法的思路,轉而執行第①條指令:「如果當前字元匹配成功(即s[i] == p[j]),則i++,j++」,可得s[i]為s[5],p[j]為p[1],即接下來s[5]跟p[1]匹配(i=5,j=1)

4. s[5]跟p[1]匹配成功,繼續執行第①條指令:「如果當前字元匹配成功(即s[i] == p[j]),則i++,j++」,得到s[6]跟p[2]匹配(i=6,j=2),如此進行下去

5. 直到s[10]為空格字元,p[6]為字元d(i=10,j=6),因為不匹配,重新執行第②條指令:「如果失配(即s[i]! = p[j]),令i = i - (j - 1),j = 0」,相當於s[5]跟p[0]匹配(i=5,j=0)

6. 至此,我們可以看到,如果按照暴力匹配演算法的思路,儘管之前文字串和模式串已經分別匹配到了s[9]、p[5],但因為s[10]跟p[6]不匹配,所以文字串回溯到s[5],模式串回溯到p[0],從而讓s[5]跟p[0]匹配。

而s[5]肯定跟p[0]失配。為什麼呢?因為在之前第4步匹配中,我們已經得知s[5] = p[1] = b,而p[0] = a,即p[1] != p[0],故s[5]必定不等於p[0],所以回溯過去必然會導致失配。那有沒有一種演算法,讓i 不往回退,只需要移動j 即可呢?

答案是肯定的。這種演算法就是本文的主旨kmp演算法,它利用之前已經部分匹配這個有效資訊,保持i 不回溯,通過修改j 的位置,讓模式串盡量地移動到有效的位置。

暴力匹配演算法,首尾匹配演算法,KMP演算法

10170330 容易 include include include define error 0 define maxsize 100 using namespace std 串的暴力匹配演算法 brute force 該函式的作用是返回子z串t在s中第position個字元之後的位置 時間複雜...

演算法 字串匹配演算法 暴力匹配演算法 KMP演算法

如果當前字元匹配成功,即 str1 i str2 j 則 i j 繼續匹配下乙個字元 如果當前字元匹配失敗,則 i i j 1 j 0 也就是每次匹配失敗時,i回溯,j被置為0 public static void main string args 暴力匹配演算法 public static int...

資料結構與演算法 暴力匹配演算法 KMP演算法

總結 如下 示例 package algorithm 暴力匹配演算法 思路 依次進行查詢 public class violencematch param s1 匹配的長字串 param s2 匹配的短字串 return 如果匹配成功,則返回長字串的第一次匹配成功的下索引,沒有則返回 1 publi...