单模式字符串匹配算法KMP

KMP算法:
2  int KMP(char* s, FILE *file, int*pos)   /**/
3 {
4   int i =0;
5     fseek(file, *pos, SEEK_SET);       /* 定位文件读位置 */
6     char c = fgetc(file);               
7   while(s[i] !='\0'&& c != EOF){
8     if(s[i] == c){                   /* 如果当前字符与c匹配,下标指向下一个字符,同时获得下一个c */
9       c = fgetc(file);
10             ++i;
11     } else                             /* 否则,下标指向当前字符的前一个匹配项 */
12             i = next[i];
13         if(i ==-1){                         /* 如果下标被赋值为-1, 从说明c之前的子串与s不符,c从新获得,下标从0开始比较 */
14             c = fgetc(file);
15             i =0;
16         }  
17   }
18   if(s[i] =='\0'){                    /* 如果下标移动到最后,则匹配成功,记录文件当前位置,同时返回匹配位置 */
19         *pos = ftell(file);
20         return*pos - strlen(s);
21     }else                                /* 否则返回-1 */
22         return-1;
23 }
获得模式串的next数组算法:(算法中c1代表文件中正在与s进行匹配的字符)
next[i]值的含义要求一下两个条件:
    条件①:存在j,满足max{0<=j<=i且s[0]~s[j]=s[i-j]~s[i]};
    条件②:在满足条件①情况下,若s[i+1]!=s[j+1],则next[i+1]=j;若s[i+1]=s[j+1],则next[i+1]=next[j+1];

1    void get_next(char* s, int next[])
2    {
3         next[0] =-1;                       /* next[0]=-1固定值 */                   
4         int i =0, j =-1;                   
5         while(s[i] !='\0'){                 /* 开始求next[i]值,直到s末尾 */
6                                                        /* 此时,next[i]已经得出 */                               
7            if(j ==-1|| s[i] == s[j] ){    /* 然后利用循环寻找满足条件①的j,直到j满足条件①或j=-1停止 */
8                                                    /* 此时有两种情况,①0<=j<=i且s[0]~s[j]=s[i-j]~s[i];②j=-1;可以统一用以下语句处理 */
9                 ++i;++j;         /* 针对以上两种情况,i和j下标都加1,以便求得下一个next[i]的值 */
10                if(s[i] != s[j])   /* ①若在s[0]~s[j-1]=s[i-j-1]~s[i-1]的情况下,有s[i]!=s[j],显然next[i]=j;
11                                         ②若在j=0的情况下,有s[i]!=s[0],则与s[i]不匹配外来的字符c,仍有可能与s[j]匹配,故next[i]=0
*/
12                    next[i] = j;           
13                else         /* ①若s[0]~s[j-1]=s[i-j-1]~s[i-1]的情况下,有s[i]=s[j],由条件①知j是max{...}的,
14                                  所以与s[i]不匹配的外来字符c1和与s[j]不匹配的外来字符c2,会被回退到同一个匹配下标,故next[i]=next[j]
15                                  ②若j=0,有s[i]=s[0],则同上情况的解释,next[i]=next[0]=-1
*/
16                    next[i] = next[j]       
17        }else                             /* 对应3行if语句不成立情况, */   
18                  j = next[j];               
19      }
20    }



    ^_^

posted @ 2010-12-31 15:36  bai yan  阅读(342)  评论(0编辑  收藏  举报