今天覆習到了串的模式匹配,有兩種演算法,一種簡單的,還有一種改良後的,稱為kmp演算法。這篇說我對kmp演算法的理解。
s串:主串;t串:子串
先說一下為什麼要改良,簡單的模式匹配效率低速度慢,而造成這種局面的根本就是一遍又一遍的返回,匹配失敗後,s串回到下乙個字元,t串回到第乙個字元,這是不必要的,這就使效率變低。
如果在某趟匹配過程中,在si和tj匹配失敗後(即 t1t1…tj-1 = si-j+1si-k+2…si-1 tj前所有字元與si前所有字元匹配成功),i不返回到s串下乙個字元,而是向右滑,存在tk前所有字元與si前所有字元匹配成功,即 t1t2…tk-1 = si-k+1si-k+2…si-1(原諒我不會打下標),k一定比j小,因為j後的字元還沒有匹配到,所以tj的前k個字元與sj的前k個字元匹配,即tj-k+1tj-k+2…tj-1 = si-k+1si-k+2…si-1,以上可知,t1t2…tk-1=tj-k+1tj-k+2…tj-1
所以只要當匹配失敗時,找出k值,就可以使tk對準si繼續匹配。
假設已有next函式情況下kmp**:
int
kmp(
char s,
char t,
int next)
if(j>t[0]
)return
(i-t[0]
);else
return0;
}
我們把要求的k值表示為next(j),next值取決於子串本身。next(1)=0是一定的。
設next(j)=k,即t1t2…tk-1=tj-k+1tj-k+2…tj-1
那麼next(j+1)等於什麼呢?
如果tk=tj,即t1t2…tk=tj-k+1tj-k+2…tj也就是next(j+1)=k+1=next(j)+1
如果tk!=tj的話,可把現在tk!=tj當做模式匹配問題,現在tk與tj不匹配,那麼應該找到k』可以繼續匹配,即next(k)=k』,tk』=tj;則t1t2…tk』=tj-k』+1tj-k』+2…tj所以next(j+1)=k』+1=next(k)+1
如果tk』!=tj一直找下去k一直減小直至1,那麼next(k)=0故next(j+1)=next(k)+1=1
**如下:
void
getnext
(char t,
int next)
}
主串
aabcbabcaabcaababc
子串abcaababc
nextj
1234
5678
9子串ab
caab
abcnext(j)01
1122
323第一趟:aa
bcba
bcaa
bcaa
babc
ab-ca
abab
cb-位置失敗,i=2,j=2,next(2)=1,故j=1,t1與s2比較
第二趟:aa
bcba
bcaa
bcaa
babc
abca-
abab
ca-位置失敗,i=5,j=4,next(4)=1,故j=1,t1與s5比較
第三趟:aa
bcba
bcaa
bcaa
babc
abca
abab
cj++;i++;
第四趟:aa
bcba
bcaa
bcaa
babc
abca
aba-b
ca-位置失敗,i=12,j=7,next(7)=3,故j=3,t3與s12匹配aa
bcba
bcaa
bcaa
babc
abca
abab
c匹配成功
以上就是所有理解啦,我是參考課本和查詢資料,自己理解並了解的,希望有什麼不足請指出。bye
模式匹配 KMP演算法
字串匹配演算法 include includeusing namespace std define ok 1 define error 0 define overflow 2 typedef int status define maxstrlen 255 使用者可在255以內定義最長串長 typed...
模式匹配KMP演算法
前些日子在為目前該學習什麼而苦惱,就問了一下已經從事多年軟體開發的表哥,他說乙個程式設計師要走的遠,就要學好資料結構和演算法,於是我就重新開始學習資料結構和演算法了 拿起以前上過的資料結構看,看到第四章串的模式匹配時,頗感興趣,就寫了一下程式,實踐了一下。感覺還蠻爽,於是就把以下幾個重要的函式放在此...
KMP模式匹配演算法
首先,這是由knuth morris和prattle三人設計的線性時間字串匹配演算法。這裡就不仔細的講解,網上有更好的講解,在這推薦幾個自己當時學習的kmp所看到的較好理解的 這裡附上自己所學的 includeusing namespace std s 是主串 p 是模式串 int next 100...