改进KMP模式匹配算法

Posted luozhonghao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了改进KMP模式匹配算法相关的知识,希望对你有一定的参考价值。

看了算法的大致步骤,然后自己一一证明了每一步的正确性,注释里写了一些理解。

这也不是新鲜的做法,只是感觉这个程序非常精巧,反复地使用数学归纳法。

让我感觉很新鲜。

 1 /*
 2     next[i]存放:match[i]处失配,orig在对应位置将要匹配的值
 3                  按照KMP的思想,
 4                  即是1到i-1子串中最长相同前后缀的前缀最后一项的后一项
 5                  且这一项和match[i]不同 
 6                  
 7                  若不存在同缀子串但是第一项与i项不同,值为1。 
 8                  若不存在同缀子串且第一项与i项相同,值为0,即将j向后移动一个位置。 
 9 */
10 #include<stdio.h>
11 int main(void)
12  {
13      char orig[100],match[100];
14     int nexterval[100],next[100],lengthOrig,lengthMatch;
15     for(lengthOrig=1;;lengthOrig++){
16         char ch;
17         scanf("%c",&ch);
18         if(ch==\n||ch== ){
19             lengthOrig--;
20             break; 
21         }
22         orig[lengthOrig]=ch;
23     }
24     for(lengthMatch=1;;lengthMatch++){
25         char ch;
26         scanf("%c",&ch);
27         if(ch==\n||ch== ){
28             lengthMatch--;
29             break;
30         }
31         match[lengthMatch]=ch;
32     }
33     next[1]=0; 
34     next[2]=1;
35     for(int i=3;i<=lengthMatch+1;i++){//next中存储若i位不匹配则将要匹配的对象 
36         int k=i-1;                  //即为 1到i-1中最长前缀最后一项的后一个数 
37         while(1){                     
38             if(k==1){
39                 next[i]=1;
40                 break;
41             }
42             if(match[i-1]==match[next[k]]){
43                 next[i]=next[k]+1; 
44                 break;
45             }
46             k=next[k];//若不能延长形成子串next[k]+1
47         }              //而且还存在子串m,那这个子串一定是前一子串的子串 
48     }
49     for(int i=2;i<=lengthMatch+1;i++){//若i!=0,match[next[i]]与match[i]一定不同 
50         if(match[i]==match[next[i]])//  若match[i]==match[next[i]]    
51             next[i]=next[next[i]];//    已经有match[next[i]]!=match[next[next[i]]] 
52     }//                                    一定有match[i]!=match[next[next[i]]] 
53     int i=1,j=1,total=0;
54     while(1){//while结束时i前面的项已经和j前面的匹配,且之前的所有匹配已经尝试过了 
55         if(i==lengthMatch+1){    
56             ++total;
57             i=next[i];
58             continue; 
59         }//i-1到头即成功匹配一次 
60         if(j==lengthOrig+1)        break;
61         //当j-1已经到头 i-1尚未到头时由于orig的长度限制已经不能匹配了 
62         if(i==0){
63             ++j,++i;
64             continue;
65         }//第一项配不上 同时向后考虑一位 
66         if(match[i]==orig[j])    ++i,++j;
67         else                    i=next[i];
68     }
69     printf("They are match for %d times.",total);
70  } 

 

以上是关于改进KMP模式匹配算法的主要内容,如果未能解决你的问题,请参考以下文章

KMP及其改进算法

kmp算法详解

KMP算法

KMP算法

KMP

字符串的模式匹配:KMP算法