C语言数据结构 BF + KMP 的简洁化代码
说到字符串匹配,这是一个老但是热度不减的话题
也是学数据结构必须要会的
代码--如果不写注释 几乎不会有人看
虽然是学计算机的 前方的路对我来说还比较迷茫
只能是---》漫天撒网抓蝴蝶---low漏陋
经过半个小时的复习 整理 想着能将代码简洁化 又不失条理
将KMP和BF的写在一起 就当做个比较吧
这种经典算法 不需要解释 至于将代码简洁化
我想 大概人人都想自己做 而且自己做出来的才有意义 别人做的除非很好 否则很难看的下去
另外 做的字符串替换 链接:字符串替换-循环
# include <stdio.h> # include <stdlib.h> # define N 101 //用户输入的字符串长度最大值为N-1 第N个存'\0' # define M 2 //用户输入的字符串长度最小值 int BF(char a[],char b[]);//BF算法 a为主串,b为被检验的串返回匹配的下标 若无返回0 int KMP(char *A,char *B);//比BF复杂度低 和BF功能相同 int gainchar(char *a,int min,int max);//模拟strlen类 对*a输入范围[min,max-1]返回字符串长度,不影响下一级输入 int main(){ char A[N],B[N]; int len; PRintf("请输入A字符串(%d---%3d):\n",M,N-1); len=gainchar(A,M,N); printf("请输入B字符串(%d---%3d):\n",1,len); gainchar(B,1,len+1); printf("注:匹配失败返回0!\n\n主串:%s\n次串:%s\nBF:匹配的位置:%d\nKMP匹配的位置:%d",A,B,BF(A,B),KMP(A,B)); return 0; } int gainchar(char *a,int min,int max)//对*a输入范围[min,max-1] 防止数组超界 并清除缓冲区 { int c,k; do{ c=-1;k=0; fgets(a,max,stdin); while(a[++c]); c=a[c-1]=='\n'&&c<max?c-1:c; if(c>=max-1) while(getchar()!='\n') k++; else a[c]='\0'; if(k||c&&(c>max||c<min))//如果用户只输入'\n'则不提示输入错误,否则提示错误 printf("输入长度有误,请重新输入!\n注:只录入(%d--%d)字节:\n",min,max-1); }while(k||c<min); return c; } int KMP(char *A,char *B)//经典算法 已经简洁化 复杂度 o(strlen(A)+strlen(B)) { int i=1,j=0,C=-1,*Q=NULL; while(B[++C]); //求主串A的长度 Q=(int *)calloc(C,sizeof(int));//申请内存存NEXVAL的值 while(i<C) //获得模式串的NEXTVAL数组 if(!j||B[i]==B[j]) { ++j; ++i; Q[i]=(B[i]-B[j]?j:Q[j]); } else j=Q[j]; i=j=0; //开始和主串匹配 while (A[i]&&B[j]) if (A[i++]==B[j]) j++; else j=Q[j]; return B[j]?0:i-j+1; //返回下标值 } int BF(char a[],char b[])//BF算法 一般o(strlen(A)+strlen(B)) 最坏o(strlen(A)*strlen(B)) { int i=0,j=0; while (a[i]&&b[j]) if (a[i++]==b[j]) // 如果匹配成功 继续比较后继字 ++j; else //否则 主串回溯 { i-=j; j=0; } return b[j]?0:i-j+1; //返回下标 }路还很长 我还在继续 加油!