三个可能要考的串匹配算法XD.
部分抄
0.暴力算法
//伪代码maybe
int StrMatch(SString S, SString P){
i = 1; j = 1;
while(i <= S[0] && j <= P[0]){
if (S[i] == P[j]){i++; j++;}
else {i = i – j + 2; j = 1}
}
if(j > P[0]) return i – P[0];
return 0;
}
1.KMP
相对暴力算法,KMP不同在于当两字符不等时,指向正文串字符的指针i不动,指向模式串的指针j=next(j),那么next(j)怎么求呢?
这么想,next(j+1)和next(j)有何关系呢?。。。直接代码。
int next[MaxStrLen]; //已算好的模式的next值
int KMP_StrMatch(SString S, SString P){
int i = 1, j = 1, m = 0;
while(i <= S[0] && j <= P[0])
if (j = 0 || S[i] = P[j]){i++; j++;}
else j = next[j]; //失配时从next[j]重新比较
if(j > P[0]) m = i – j + 1;
return(m);
}
//求next数组
int next[MaxStrLen];
void get_next(SString P) {
j = 1; next[1] = 0; k = 0;
while(j <= P[0])
if (k == 0‖P[k] = P[j])
{
++k; ++j; next[j] = k;
} //next(j+1)=k +1
else k = next[k];
}
2.Boyer-Moore算法
考虑两点优化:
1.一般匹配都是从左到右到后面发现不同,因此浪费了时间,于是考虑从右向左匹配。
2.发现不等时,移动i+dist(si)距离,dist(si)表示正文字符s[i]在模式串最后(最右)出现的位置。
int BM_string_Matching(char *s,char *p){
int i, j, m, n;
m=p[0]; n=s[0]; i=m;
while(i<=n){
j = m; k = i;
while(j>0 && p[j] == s[k]){
j--; k--;}
if(j==0) return(i-m+1);
else i+=dist[s[i]];
}
//计算dist数组
Void Computer_Distance(char *P){
int i, j, m;
m = P[0];
for(i = 0; i < 256; i++)
dist[i] = m;
for(j = m –1; j > =1; j – –)
if(dist[P[j]] = = m)
dist[P[j]] = m – j;
}
3.KARP-RABIN串匹配随机算法
如果能把串相等比较转化为整数的比较该有多好?
(开始YY:)于是我们可以把串(完美)hash为整数,随正文串指针的移动递推计算hash值,与模式串比较即可。
int K-RMatch(char *t,int n,char *p,int m){
int i, j, k, z = 1, x = 0, y = 0;
for(i = 1; i < m; i++) z=(z*d) mod q;
for(i = 1; i <= m; i++){
x = (x * d + asc(p[i])) mod q;
y = (y * d + asc(t[i])) mod q;
}
}
i = 1;
while(i <= n – m){
if(x = = y){
k = 1; j = i;
while(t[j] = p[k] && k <= m)
{ j++; k++; }
if(k > m) return(i)
if(i +1< n – m){
y = ((y – z * t[i])*d + t[i + m]) mod q;
i++;
}
return(0);
}
}
ps:代码不是我写的,禁止转载。

浙公网安备 33010602011771号