数据结构 KMP 算法实现
数据结构 KMP 算法实现
KMP 算法关键是要求出next数组下面是求next数组的算法
n利用next[0]= -1,…,next[i] 求next[i+1] 的算法:
假设 k =next [i],
1) 若pk = pi, 则 p0… pi-k…pi 中最大相同前后缀长度为next[i+1] = k+1
2)若pk ¹ pi ,置 k=next[k] ,然后转到 第1步.
(设 k = next[k],就是考虑前一个更短的匹配前缀,从那里继续向下检查)
3)若 k 值(来自next)为-1,就得到p0… pi-k…pi中最大相同前后缀的长度为k = 0(即next [i+1] = 0)
对求next数组的改进
n当 pi != tj 时,若pi == pk, 那么一定有 pk != tj .所以模式串应再向右移 k-next[k]位,下一步用 pnext[k] 与tj比较
n对于next[i]=k 的改进:
if (pk== pi) next[i] = next[k]; else next[i]=k;
这一改进可以避免一些不必要的操作.
下面是一个例子:
1 /*============================================================================*\
2 *
3 * 数据结构基础练习
4 *
5 * KMP 算法测试
6 *
7 * 2013-05-20 by 樊列龙
8 *
9 \*============================================================================*/
10
11 #include <iostream>
12
13 using namespace std;
14
15 void set_next(char* p, int* next)
16 {
17 int i = 0, j= -1;
18 next[0] = -1;
19
20 while(p[i])
21 {
22 while(j >= 0 && p[i] != p[j])
23 {
24 j = next[j];
25 }
26 i++,j++;
27 if(p[i] == p[j]) next[i] = next[j];
28 else next[i] = j;
29
30 }
31 }
32
33 int KMP(char* s, char* p, int *next, int n)
34 {
35 int i = 0,j = 0;
36 int count = 0;
37 while(s[i] && j < n)
38 {
39 if(j == -1 || s[i] == p[j])
40 {
41 j++,i++;
42 count++;
43 }
44 else
45 {
46 j = next[j];
47 }
48 }
49
50 if(j >= n)
51 {
52 return i-n+1;
53 }
54
55 return 0;
56 }
57
58 int main()
59 {
60 char s[] = "abaabca8934baaabaabc23abaabcaca2312";
61 char p[] = "abaabcac";//8个字符
62 int next[100];
63
64 set_next(p,next);
65 cout << KMP(s,p,next,sizeof(p)-1) << endl;
66
67 return 0;
68 }
结果:
23