模式匹配 KMP演算法

2021-10-02 16:23:57 字數 2169 閱讀 7587

今天覆習到了串的模式匹配,有兩種演算法,一種簡單的,還有一種改良後的,稱為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...