关于KMP算法

在学KMP算法时,我发现一个新的实现方式,事先申明,我不能确定这就是KMP,我称其为LikeKMP,为了对比,我把http://www.cnblogs.com/zzyleoo/p/3366140.html这篇文章的算法与我的做了对比,以下是详细代码:

strLikeKMP.h

1 #pragma once
2 
3 int LikeKMP(char* father, char* son);
4 
5 int Index_KMP(char* S, char* T, int pos);
6 
7 int KMP(char* S, char* T);
View Code


strLikeKMP.cpp

 1 #include "strLikeKMP.h"
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5 
 6 int LikeKMP(char* father, char* son)
 7 {
 8     int f = strlen(father);
 9     int s = strlen(son);
10     int i, j;
11     int num = 0;
12 
13     i = 0;
14     while (i <= f - s)//可行范围
15     {
16         for (j = 0; j < s; j++)
17         {
18             num++;
19             if (son[j] != father[i + j]) break;//失败
20 
21             if (j == s - 1)//是否结束
22             {
23                 cout << "LikeLMP比较次数为" << num << "次\n";
24                 return i;
25             }
26         }
27         if (j != 0) j--;
28         i += j + 1;
29     }
30     cout << "LikeLMP比较次数为" << num << "次\n";
31     return -1;
32 }
33 
34 void get_next(char* T, int *next)
35 {
36     int i, j;
37     i = 1;
38     j = 0;
39     next[1] = 0;
40     
41     while (i < strlen(T))
42     {
43         if (j == 0 || T[i] == T[j])
44         {
45             ++i;
46             ++j;
47             next[i] = j;
48         }
49         //以T="abcdex"为例:该循环的执行顺序:
50         //第一步,j=0,执行,(i=2,j=1,next[2]=1)
51         //第二步,不符合循环条件,j=next[1]=0,j又变为0
52         //为了再次进入循环,(i=3,j=1,next[3]=1)依次往下循环
53         else
54             j = next[j];
55     }
56 }
57 //这段代码的目的就是为了计算出当前要匹配的串T的next数组
58 
59 int Index_KMP(char* S, char* T, int pos)
60 {    
61     int i = pos - 1;
62     int j = 0;
63     int next[255];
64     get_next(T, next);
65     int num = 0;
66     while (i < strlen(S) && j < strlen(T))
67     {
68         num++;
69         if (j == 0 || S[i] == T[j])
70         {
71             ++i;
72             ++j;
73         }
74         else
75             j = next[j];//起到回溯的作用
76     }
77     cout << "KMP 比较次数为" << num << "次\n";
78     if (j >= strlen(T))
79         return i - strlen(T);
80     else
81         return -1;
82 }
83 
84 
85 int KMP(char* S, char* T)
86 {
87     return Index_KMP(S, T, 1);
88 }
View Code


main.cpp

 1 #include "strLikeKMP.h"
 2 #include <iostream>
 3 using namespace std;
 4 #define SIZE 128
 5 
 6 void numshow(int n)
 7 {
 8     cout << "          ";
 9     for (size_t i = 0; i < n; i++)
10     {
11         cout << i%10;
12     }
13     cout << endl;
14 }
15 
16 int main(void)
17 {
18     int num;
19     cout << "试验次数:";
20     cin >> num;
21 
22     char father[SIZE];
23     char son[SIZE];
24     while (num--, num >= 0)
25     {    
26         fflush(stdin);
27         cout << "父串内容:";    
28         cin >> father;
29         numshow(strlen(father));
30 
31         fflush(stdin);
32         cout << "子串内容:";        
33         cin >> son;
34 
35         cout << "\tLikeKMP:\t"<< LikeKMP(father, son) << endl;
36         cout << "\tKMP:\t\t" << KMP(father, son) << endl;
37         cout << "\tIndex_KMP:\t" << Index_KMP(father, son,1) << endl;
38         cout << endl;
39     }
40 
41     return 0;
42 }
View Code

 

运行结果让人感到意外,有点时候Index_KMP是对的,有的时候KMP,具体情况,我在下面给了一个例子

以下是源码下载链接http://pan.baidu.com/share/link?shareid=2130189571&uk=3994249334

 

 

posted @ 2013-10-13 09:10  ligelaige  阅读(173)  评论(0)    收藏  举报