Lec2-KMP实现

贴代码:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 //kmp:快速字符串匹配
 6 
 7 //关于返回值:需要返回一个大小为pattern_size的存放next值的数组,如果只在函数中定义临时变量的数组,则无法返回值;
 8 //而如果在函数中new一个数组返回,则需要在外面delete,违反了程序设计的准则。
 9 //较好的方法是在main中构造一个数组然后把首指针传到函数中去
10 
11 //关于函数设计:先给出递推式,明确设计方法
12 //next函数设计方法:(1)next[1]=0;当比较不相等时且遇到next[1]=0,说明遇到串头,主串需要往后移一位
13 //递推:当next[j]=k时,有P1....Pk-1 = Pj-k+1....Pj-1   (2)若Pj = Pk,则next[j+1] = k + 1 = next[j] + 1
14 //(3)若Pj != Pk,因为有P1....Pk-1 = Pj-k+1....Pj-1,对于next[k] = k'也会满足k'之前的字符等于j之前的字符,这种性质能通过next函数传递
15 //于是递推移动k' = next[k],若有Pj = Pk',则next[j] = k' +1。如果遇到next[1]=0,则next[j] = 1。
16 void compute_next(char * pattern,int len, int *next)
17 {
18     next[1= 0;//next函数对应的是模式串的位数
19     int j = 1;
20     while(j < len) 
21     {
22         int k = next[j];
23         //if(k == 0)     { next[j+1] = 1;cout<<j+1<<next[j+1]<<endl;  j++; continue;}
24         //if (pattern[j-1] == pattern[k-1]) 
25         //{
26         //    next[j+1] = next[j] +1;
27         //    cout<<j+1<<next[j+1]<<endl;
28         //}
29         //else
30         //{           //有一个简化的过程
31             while(k != 0)
32             {
33                 if (pattern[j-1== pattern[k-1])  
34                 {
35                     next[j+1= k + 1;
36                     cout<<j+1<<next[j+1]<<endl;   //经验:将中间结果输出可以节省调试时间,快速发现问题(避免单步!)
37                     break;
38                 }
39                 k = next[k]; //这种迭代的方法很巧妙,看书~
40             }
41             if(k == 0
42             {
43                 next[j+1= 1;
44                 cout<<j+1<<next[j+1]<<endl;
45             }
46         //}
47         j++;
48     }
49 }
50 
51 int kmp(char* source,int lens,char* pattern,int lenp,int *next)
52 {
53     int i =1, j=1;
54     while(i<=lens&&j<=lenp)
55     {
56         if (j == 0 || source[i-1== pattern[j-1])
57         {
58             i++;
59             j++;
60         }
61         else j = next[j];
62     }
63     if(j>lenp) return (i - lenp);
64     else return 0;
65 }
66 
67 int main()
68 {
69     char source[100];
70     char pattern[100];
71     int s_size,p_size;
72 
73     while(1)
74     {
75 
76         cout<<"Input the first string:";
77         cin>>source;
78         cout<<"Input the second string:";
79         cin>>pattern;
80         s_size = strlen(source);
81         p_size = strlen(pattern);
82 
83         int next[100];
84         compute_next(pattern, p_size,  next); 
85         //kmp算法的关键是求出模式串的next函数,即当前模式串的第j位与目标串的第i位不相等时,
86         //下一步应使用模式串的next(j)位与目标串第i位进行比较
87         //next(j)=k,即有P1....Pk-1 = Pj-k+1....Pj-1
88         int result = kmp(source,s_size,pattern,p_size,next);
89         cout<<"The substring index is "<<result<<endl;
90     }
91 }

 

posted @ 2011-04-28 18:13  Avril  阅读(221)  评论(0编辑  收藏  举报