參見原文
簡單模式匹配演算法
經典的模式匹配,是讓模式串的首字元從主串的首字元開始向右匹配。
匹配的規則是:
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...
簡單模式匹配演算法 串的模式匹配
一 對乙個串中的某子串的定位操作稱為串的模式匹配 二 模式串 待定位的子串 三 基本思想 從主串中的第乙個位置起和模式串的第乙個字元開始比較 如果相等,則繼續比較後續字元 如果不等,則從主串的第二個字元起,重新用上一步的方法與模式串中的字元作比較 以此類推,直到比較完模式串的所有字元,則匹配成功,返...