三个可能要考的串匹配算法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:代码不是我写的,禁止转载。

 

posted @ 2014-06-11 23:21  Ramanujan  阅读(172)  评论(0)    收藏  举报