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 }
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 }
你问我生命中还有什么可追寻?