标签:style http color os io 使用 ar strong for
kmp算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是根据给定的模式串W1,m,定义一个next函数。next函数包含了模式串本身局部匹配的信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
intKMP(stringW,stringT){ inti=1,j=1; while (i<=n){ while (j!=0&&W[j]!=T[i]){ j=next[j]; } if (j==m){ returni-m+1; //success,returnthefirstmatchposition } else { j++;i++; } } return -1; //failure } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
procedureKMP begin i= 1 j= 1 whilei<=ndo whilej<>0andW[j]<>T[i] do j=newnext[j] endwhile ifj=m return“success” else j++ i++ endif endwhile return“failure” end |
1
2
3
4
5
6
7
8
9
10
11
12
|
voidgetNext(stringW){ for (inti=1;i<m;i++){ intj=i; while (j>0){ j=next[j]; if (W[j]==W[i]){ next[i+1]=j+1; break ; } } } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
functionNEXT begin next[ 1 ]=newnext[ 1 ]= 0 j= 2 whilej<=mdo i=next[j- 1 ] whilei<>0andW[i]<>W[j- 1 ]) do i=next[i] endwhile next[j]=i+ 1 j=j+ 1 endwhile end functionNEWNEXT begin newnext⑴= 0 j= 2 whilej<=mdo i=next(j) ifi=0orW[j]<>W[i+ 1 ] newnext[j]=i else newnext[j]=newnext[i] endif j++ endwhile end |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
voidGetNext(charT[],intnext[]) { next[1]=0; j=1;k=0; while (j<T[0]) if ((k==0)||(T[j]==T[k])) { j++; k++; next[j]=k; } elsek=next[k]; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
procedureBM begin i=m Repeat j=m k=i while (j> 0 ) and (w[j]=t[k]) do j=j- 1 k=k- 1 endwhile i=i+d[t[i]] Until (j= 0 ) or (i>n) Ifj=0return“SUCCESS” elsereturn“FAILURE” endif end |
1
2
3
4
5
6
7
8
9
|
functiond:integer; begin forx∈∑dod(x)=m forj=m-1downto1do ifd(w[j])=md(w[j]):=m-j endfor end xi+1=ord(ti+1)dm-1+ord(ti+2)dm-2+…+ord(ti+m) =(xi-ord(ti)dm-1).d+ord(ti+m) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
programRK; begin {计算x,x:=d↑(m-1)modq} x=1 fori=1tom-1dox=(32*x)modq {计算模式W的散列函数值} s=0 fori=1tomdo s=((s*32)+ord(w[i]))modq {计算正文T的第一个长度为m的字符段的散列函数值} t=0 fori=1tomdo t=(t*32+ord(w[i]))modq {如果正文的第一个长度为m的字符段和模式有相同的散列函数值,则进行匹配检查.否则,以及在匹配检查失败情况下,继续计算下一个字符段的散列函数值} i=1 whilei<=n-mdo ifs=t {进行匹配检查} k=1 j=i while(t[j]=w[k])and(k<=m)do j=j+1 k=k+1 endwhile ifi<n-m{计算下一字符段的散列函数值} t=((t-x*ord(t[i]))*32+ord(t[i+m]))modq i=i+1 endif endif endwhile return“FAILURE” end |
下标i
|
0
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
9
|
p(i)
|
a
|
b
|
c
|
d
|
a
|
a
|
b
|
c
|
a
|
b
|
next[i]
|
-1
|
0
|
0
|
0
|
0
|
1
|
1
|
2
|
3
|
1
|
下标i
|
0
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
9
|
p(i)
|
a
|
b
|
c
|
d
|
a
|
a
|
b
|
c
|
a
|
b
|
next[i]
|
-1
|
0
|
0
|
0
|
0
|
1
|
1
|
2
|
3
|
1
|
优化的next[i]
|
-1
|
0
|
0
|
0
|
-1
|
1
|
0
|
0
|
3
|
0
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
voidgetNext(constchar*pattern,intnext[]) { next[0]=-1; intk=-1,j=0; while (pattern[j]!= ‘\0‘ ) { while (k!=-1&&pattern[k]!=pattern[j])k=next[k]; ++j; ++k; if (pattern[k]==pattern[j]) next[j]=next[k]; elsenext[j]=k; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#include<iostream> #include<stdlib.h> #include<vector> usingnamespacestd; inlinevoidNEXT(conststring&T,vector< int >&next) { //按模式串生成vector,next(T.size()) next[0]=-1; for (inti=1;i<T.size();i++){ intj=next[i-1]; while (T[i]!=T[j+1]&&j>=0) j=next[j]; //递推计算 if (T[i]==T[j+1])next[i]=j+1; elsenext[i]=0; // } } inlinestring::size_typeCOUNT_KMP(conststring&S, conststring&T) { //利用模式串T的next函数求T在主串S中的个数count的KMP算法 //其中T非空, vector< int >next(T.size()); NEXT(T,next); string::size_typeindex,count=0; for (index=0;index<S.size();++index){ intpos=0; string::size_typeiter=index; while (pos<T.size()&&iter<S.size()){ if (S[iter]==T[pos]){ ++iter;++pos; } else { if (pos==0)++iter; elsepos=next[pos-1]+1; } } //whileend if (pos==T.size()&&(iter-index)==T.size())++count; } //forend returncount; } intmain(intargc, char *argv[]) { stringS= "abaabcacabaabcacabaabcacabaabcacabaabcac" ; stringT= "ab" ; string::size_typecount=COUNT_KMP(S,T); cout<<count<<endl; system ( "PAUSE" ); return0; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
PROGRAMImpl_KMP; USESCRT; CONSTMAX_STRLEN= 255 ; VARnext: array [ 1.. MAX_STRLEN]ofinteger; str_s,str_t: string ; int_i: integer ; Procedureget_nexst(t: string ); Varj,k: integer ; Begin j:= 1 ;k:= 0 ; whilej<Length(t)dobegin if (k= 0 ) or (t[j]=t[k])thenbegin j:=j+ 1 ;k:=k+ 1 ; next[j]:=k; end elsek:=next[k]; end ; End ; Functionindex(s: string ;t: string ): integer ; Vari,j: integer ; Begin get_next(t); index:= 0 ; i:= 1 ;j:= 1 ; while (i<=Length(s)) and (j<=Length(t))dobegin if (j= 0 ) or (s[i]=t[j])thenbegin i:=i+ 1 ;j:=j+ 1 ; end elsej:=next[j]; ifj>Length(t)thenindex:=i-Length(t); end ; End ; BEGIN ClrScr; {清屏,可不要} Write (‘s=’); Readln(str_s); Write (‘t=’); Readln(str_t); int_i:=index(str_s,str_t); ifint_i<>0thenbegin Writeln ( ‘Found‘ ,str_t, ‘in‘ ,str_s, ‘at‘ ,int_i, ‘.‘ ); end elseWriteln( ‘Cannotfind‘ ,str_t, ‘in‘ ,str_s, ‘.‘ ); END . |
标签:style http color os io 使用 ar strong for
原文地址:http://www.cnblogs.com/yongwangzhiqian/p/3957287.html