簡單模式匹配演算法和KMP演算法

2021-10-07 19:56:31 字數 1957 閱讀 7680

參見原文

簡單模式匹配演算法

經典的模式匹配,是讓模式串的首字元從主串的首字元開始向右匹配。

匹配的規則是:

1.在主串的第i個位置,讓pos=i,如果主串pos位置的字元等於模式串的第乙個字元,則pos++,再與模式串的第二個字元進行匹配。

2.如果又相等則繼續向下匹配,直到匹配到模式串的結尾,就說明主串中存在該模式串;如果不相等,則停止匹配,回到主串中,並i++。

3.然後再讓pos=i,重複上述步驟,直到i到達主串結尾。

相應**如下:

#include

#include

intmain()

//否則中斷與模式串的匹配

else

break;}

//判斷與模式串是否完全匹配,若是則輸出i位置

if(pos-i==lenp)

printf

("\npattern start in %d"

,i);

}}

kmp模式匹配演算法

kmp演算法的好處就是不用回溯,而是以一種滑動的方式向下匹配模式串。

假設next陣列

首先,我們假設對於模式串有乙個next陣列。

該陣列值的含義是:模式串第0位後長度為next[j]的字串,與第j位(從0開始,除0外)前長度為next[j]的字串相等,同時next[j]值要竟可能大,但兩個字串又不能重合。特例:第0位的next值為-1。

例如:abcac模式串的next陣列值依次為[-1,0,0,0,1]。模式串中第4位(從0開始)字元c的next值為1,表明字元c前長度為1的字串即a,與從0位開始長度為1的字串即a相等。其餘位,除0位外,next值都為0。

再例如:0001模式串的next陣列值依次為[-1,0,1,2]。

利用next陣列進行模式匹配

在普通模式匹配中,主串pos位與模式串j位不匹配時,主串回到i+1位重新與模式串0位進行匹配。

有了next陣列,我們便不用回溯到i+1位重新匹配了。而是用主串pos位與模式串next[j]位進行匹配,若還是不匹配,則轉到next[next[j]]。直到next的值等於-1,模式串滑動到主串pos+1位重新匹配。

其實,當不匹配求next[j]值時,就是將模式串向下滑動的過程。其原理是因為next陣列的特殊性:

模式串第0位後長度為next[j]的字串,與第j位(從0開始,除0外)前長度為next[j]的字串相等。

#include

#include

#include

// 獲取模式串的next陣列函式:

// 將模式串既當作「主串」又當作模式串,同樣按照kmp的演算法進行匹配求next值。

void

getnext

(char

*str,

int*next,

int n)

// 如果「主串」i位置的前一位和模式串j位置相同,則「主串」i位置的next值為j+1。

// 同時「主串」與模式串繼續向下匹配。

else

if(str[i-1]

== str[j]

)// 如果不匹配,則前進到模式串的next[j]位置

else j=next[j];}

}int

main()

// 如果主串i位置與模式串j位置相等,則i、j都向下繼續配對

else

if(str[i]

== pat[j])}

// 如果模式串j位置與主串i位置不匹配,則將模式串向後滑動,

// 用模式串的next[j]位置與主串i位置匹配

else j=next[j];}

free

(next)

;return0;

}

KMP(單模式匹配)

單字串匹配,返回匹配位址 求出匹配總次數 求迴圈元,t len next len next陣列的有效範圍是 0,len len的時候,next為有效值 只需要記住next 0 1,next 1 0,這兩個條件就可以寫出求next的函式 匹配過程只需要o n 所以i的值不需要回歸。這裡曾經糾結很久,m...

單模式字串匹配演算法KMP

kmp演算法 2int kmp char s,file file,int pos 3 else 否則,下標指向當前字元的前乙個匹配項 12i next i 13if i 1 17 18 if s i 0 else 否則返回 1 22 return 1 23 獲得模式串的next陣列演算法 演算法中c...

簡單模式匹配演算法 串的模式匹配

一 對乙個串中的某子串的定位操作稱為串的模式匹配 二 模式串 待定位的子串 三 基本思想 從主串中的第乙個位置起和模式串的第乙個字元開始比較 如果相等,則繼續比較後續字元 如果不等,則從主串的第二個字元起,重新用上一步的方法與模式串中的字元作比較 以此類推,直到比較完模式串的所有字元,則匹配成功,返...