KMP算法与传统字符串寻找算法

2023-05-28,,

原理:KMP算法是一种模板匹配算法,它首先对模板进行便利,对于模板中与模板首字符一样和首字符进行标志-1,对于模板匹配中出现不匹配的若是第一轮检查标志为0,若不是第一轮检查标志为该元素与标志为-1的距离,在便利时通过检查有-1标签的数据标签进行往后检查,若不匹配,则直接跳到不匹配的位置(哨兵标记)进行往后检查。

#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>

typedef struct string string;
struct string
{
char *str;
int length;
};

double get_sys_time(void)
{
struct timeval time;
gettimeofday(&time,NULL);
return ((double)time.tv_sec + (double)time.tv_usec * 1.e-6);
}

string creat_string(int length)
{
string tmp_string;
tmp_string.str = (char *)malloc(sizeof(char) * (length + 1));
tmp_string.length = length;
return tmp_string;
}

string insert_string(char * str)
{
string tmp_string;
tmp_string.str = str;
tmp_string.length = strlen(str) + 1;
printf("sizeof str: %d\n",tmp_string.length);
return tmp_string;
}

int pure_find(string str,char * find_str)
{
int i = 0;
int j = 0;
while(*(str.str + i) != '\0')
{
if(*(find_str + j) == '\0') break;
if(*(str.str + i) == *(find_str + j))
{
j++;
}
else
j = 0;
i++;
}
if(i-j == str.length - 1) return -1;
return i - j;
}

int* find_Next(char *str)
{
int * Next;
Next = (int *)malloc(sizeof(int) * strlen(str));
int i = 0;
int j = 1;
int sentinel = 0;
Next[0] = -1;
int flags = 0;

while(str[j] != '\0')
{
if(str[0] == str[j] || str[j] == str[i])
{

if(str[0] == str[j])
{
Next[j] = -1;
sentinel = j;
flags = 1;
}
else
Next[j] = 0;
i++;

}
else
{
i = 0;
if(0 == flags)
Next[j] = 0;
else Next[j] = j - sentinel;
}
j++;
}

for(int circle = 0;circle < strlen(str);circle++)
{
printf("%3d",Next[circle]);
}
printf("\n");
return Next;
}

int KMP(int * Next,char * find_str,string str)
{
int sentinel = 0;//定义一个哨兵用于存放匹配错误时的消息
int j = 0;
int length = strlen(find_str);//获取到匹配字符串的长度
while(str.str[sentinel]!='\0')
{
if(j == -1 || str.str[sentinel] == find_str[j])
{
sentinel++;
j++;
}
else
{
j = Next[j];
}
if(j == length)
return sentinel - j;//到达模板长度
}
return -1;
}

int main(int argc,char *argv[])
{
string tmp_str;
//printf("argv:%s\n",argv[--argc]);
tmp_str = insert_string("XiaoXiaoXiaoEr");
double time = get_sys_time();
int num = pure_find(tmp_str,argv[argc - 1]);
printf("%s\n",argv[argc-1]);
time = get_sys_time() - time;
printf("pure cost time: %lf s\n",time);
if(num == -1)
{
printf("never find\n");
//return 0;
goto LOOP;
}
printf("出现在第 %d 位置\n",num);
LOOP: time = get_sys_time();
int *Next = find_Next(argv[argc - 1]);
num = KMP(Next,argv[argc - 1],tmp_str);
time = get_sys_time() - time;
if(num == -1)
{
printf("never find\n");
printf("KMP cost time: %lf s\n",time);
return 0;
}
printf("KMP cost time: %lf s\n",time);
printf("出现在第 %d 位置\n",num);

return 0;
}

KMP算法与传统字符串寻找算法的相关教程结束。

《KMP算法与传统字符串寻找算法.doc》

下载本文的Word格式文档,以方便收藏与打印。