您的位置:首页 > 编程语言 > C语言/C++

C语言KMP算法的实现

2017-01-19 20:47 344 查看
        KMP算法在需要大量元素进行对比的时候比BF算法更为快速。注意,接下来的串都是以下标为1作为起始储存位置。
下面说一下实现代码:
        首先是函数头、预定义和类型定义:

#define MAXLEN 100

typedef struct{
char ch[MAXLEN + 1];
int length;
}SString;

KMP算法主体函数:

int Index_KMP(SString S, SString T, int pos)
{
int i, j;
int next[MAXLEN + 1];
i = pos;
j = 1;
get_next(T, next);
while (i < S.length&&j < T.length)
{
if (j == 0 || S.ch[i] == T.ch[j])
{
++i;
++j;
}
else
j = next[j];
}
if (j >= T.length)
return i - T.length + 1;
else
return 0;
}

     先对模式串T的next[]进行取值,具体实现函数get_next()下面给出。将pos的值赋值给i,表示从元素的第pos个值开始对比;让j等于1,表示模式串T从第一个元素开始对比。当j等于0的时候,表示之前没有任何元素相同,且此时i和j都在下一轮该对比的元素的前一位,所以让i和j均加1。当i小于S.length并且j小于T.length的时候,将S.ch[i]和T.ch[j]进行对比,若相等,则对比下一位元素,若不相等,则让j回到模式串T开头和模式串T的j之前匹配的位置。最后当跳出循环的时候,若j的值大于或等于T.length的话,则说明匹配成功,返回该位置;否则表示匹配失败,返回0.
    接下来是对结构串的next[]进行取值的函数get_next():
void get_next(SString T, int next[])
{
int i, j;
next[1] = 0;
i = 0;
j = 1;
while (j < T.length)
{
if (i == 0 || T.ch[i] == T.ch[j])
{
++i;
++j;
next[j] = i;
}
else
i = next[i];
}
}

        在看这段代码之前,先理解next[i]的值。个人理解,next[i]记录着开头与当前位置前一位元素匹配的元素的位置。让next[1]=0,在对比过程中,当存在不相等的情况的时候,若此时i=1,则i会等于0,此时模式串T的i,j都在对比元素的前一位,则让i,j都加1,并且让T中下标j的位置指向位置标记为1,回到第一位元素。

        加入main()进行测试:

int callen(SString S)
{
int i;
for (i = 0; S.ch[i] != '\n'; i++);
return i;
}

int main(void)
{
SString S, T;
int pos = 1, n, i;
for (i = 1; S.ch[i - 1] != '\n'; i++)
{
S.ch[i] = getchar();
}
S.length = callen(S);
fflush(stdin);
for (i = 1; T.ch[i - 1] != '\n'; i++)
{
T.ch[i] = getchar();
}
T.length = callen(T);
n = Index_KMP(S, T, pos);
printf("%d\n", n);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 数据结构