/*
* @FileName: simKMP.c
* @Author: wzj
* @Brief:
* 1.测试版本的kmp
*
*
*
*
* @History:
*
*
*
* @Date: 2012年06月03日星期日22:05:45
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//improved one
void
get_next_imp(char *dst, int *next)
{
int j = 0;
int k = -1;
int dst_len = strlen(dst);
next[0] = -1;
while(j < dst_len)
{
if(k == -1 || dst[k] == dst[j])
{
next[j+1] = k+1;
if(dst[j+1] == dst[next[j+1]])
{ //加速跳转,一次性跳过更多字符
//例如abcabcabc 直接关联到最初的一个
//因为从左往右来的,可以保证, 没有什么递归的操作
next[j+1] = next[next[j+1]];
}
j++;
k++;
} else {
k = next[k];
}
}
}
//generate the next[]
void
get_next(char *dst, int *next)
{
int j = 0; //从0开始
int k = -1;
int dst_len = strlen(dst);
//做终结标记
next[0] = -1;
//每次访问,都用来确定之后的一个
while(j < dst_len)
{
if(k == -1 || dst[k] == dst[j])
{ //如果为k=-1也就是到达第一个了,那么next[j+1]指向开头
//如果dst[k] == dst[j],那么,说明两者包括之前的串都是匹配的
//j+1 == k+1
next[j + 1] = k + 1;
j++;
k++;
} else {
//这个相当于说匹配失败,保证之前的元素匹配!回到之前的一个
//相似的串,继续匹配
k = next[k];
}
}
}
//kmp main
int
kmp(char *target, char *patten, int pos, const int *next)
{
int i = pos;
int j = 0;
while(target[i] != '\0')
{
if(j == -1)
{//如果j ==-1 重新开始
i++;
j++;
}
if(patten[j] == '\0')
{ //匹配结束,返回位置。 +1保证结果是从1开始计算的第n个字符
return i - j + 1;
}
if(target[i] == patten[j])
{ //匹配上了,没说的,继续
i++;
j++;
} else {
//借助next,解决匹配分歧, 进行跳转
j = next[j];
}
}
return 0;
}
//compare the next ...
void
print_next(char *patten, int *next)
{
int i = 0;
int patten_len = strlen(patten);
printf("current patten: %s\n", patten);
printf("next is:");
for(i = 0; i < patten_len; i++)
{
printf("%d ", next[i]);
}
printf("\n");
}
int
main()
{
char *patten = "abcabcabcabcabc";
char *dst = "adfjabcmabcsabclabceabcdabcmabcejf";
int patten_len = strlen(patten);
int *next = (int*) malloc(patten_len * sizeof(int));
if(next == NULL)
{
printf("malloc failed\n");
return 0;
}
get_next(patten, next);
get_next_imp(patten, next);
int pos = 0;
pos = kmp(dst, patten, 0, next);
printf("dst string: %s\n", dst);
//没有压缩的next比较保守地进行跳转
get_next(patten, next);
print_next(patten, next);
//尽可能地跳转,保证相同的子串可以做到最大距离跳转
get_next_imp(patten, next);
print_next(patten, next);
printf("match pos: %d\n", pos);
return 0;
}
KMP--比较清晰的一份
最新推荐文章于 2024-10-15 17:16:46 发布