最近复习数据结构,看到了KMP串匹配算法,是现在效率很高的一种匹配算法,但是对于老师教学来说,这个算法比较难理解,笔者也没有吃透,只知道大概思路。
它和普通的比较在于,不是一个字符一个字符的比较,因为那样很浪费时间,而是在事先对我要比对的子串进行一次reckonValue,即计算每个字符在这个字符串中的value值,在和主串进行比较,当遇到不同的字符时候,根据value值重新定位下一个要比较的字符,避免从来再比较而造成的时间浪费!
下面是笔者这几天抽空写出的c语言描述算法,经过测试,给大家学习参考交流一下!
/********************************************************************** 头文件------head file **********************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> /********************************************************************** 宏定义------macro definition **********************************************************************/ #define EQ( a, b) a == b && (a & b) //判断是否相等的宏定义 #define debug 1 //调试用的裁剪宏定义 /************************************************************************* 结构体的定义-----------struct definition *************************************************************************/ typedef struct { char data; int value; }Value; /************************************************************************* 函数名称:__reckonValue 函数表述: 为内部函数,用于KMP匹配算法时,计算value的值 输入值: string *child 返回值: 计算成功返回计算后的结果,否则返回NULL *************************************************************************/ Value * __reckonValue(char *child) { int i,j; //计算value的两个变量 int length; //存入长度 Value *datavalue; length = strlen(child); datavalue = (Value *)malloc(sizeof(Value)*length); if(datavalue == NULL) { puts("为KMP算法计算value开辟空间失败"); return NULL; } for(i = 0; i < length; i++) { datavalue[i].data = child[i]; //将值传入到数组中 } datavalue[0].value = 0; //初始化第一个字符为0 i = 1; //i指向第二个字符 while(i <= length) { j = i - 1; while(datavalue[i].data != datavalue[j].data //停止的条件为扫描 && j > 0) //到第0个数据了或者遇到相等的数据 { j --; } datavalue[i].value = datavalue[j].value + 1; //加1,得到value i ++; //计算后一个 } #if debug == 1 for(i = 0;i < length;i ++) { printf("%c ",datavalue[i].data); } puts(""); for(i = 0;i < length;i ++) { printf("%d ",datavalue[i].value); } puts(""); #endif return datavalue; } /************************************************************************* 函数名称:matchString 函数表述: KMP串匹配算法的主要函数 输入值: string *main,string *child 返回值: 匹配成功返回子串在主串中的起始位置,否则返回-1 *************************************************************************/ int matchString(char *main,char *child) { Value *childvalue; //接收value 值 int mainlength,childlength; int i,j; mainlength = strlen(main); childlength = strlen(child); if(main == NULL //判断主串与子串是不是合法的 ||child == NULL) { puts("字符串不合法"); return -1; } else if(mainlength < childlength) //判断主串与子串在长度上是否合法 { puts("子串长度大于主串长度"); return -1; } childvalue = __reckonValue(child); //调用内部函数,计算value的值 i = 0; j = 0; while(i <= mainlength && j <= childlength) { for(;EQ(main[i],child[j]);i++,j++); //进行比对 if(j == childlength ) { return i - childlength ; //此时表示是子串返回初始位置 } i ++; //若不成功则继续运行算法 j = childvalue[j].value; //重新定位j,为次元素的跨度 } return -1; } int main() { char child[] = "abcacabc"; char main[] = "ababcabcacabc"; printf("%d/n",matchString(main,child)); return 0; }

被折叠的 条评论
为什么被折叠?



