字符串查找-bf kmp

来源:互联网 发布:哪个软件有姜草漫画 编辑:程序博客网 时间:2024/06/05 02:14

字符串可以通过bf和kmp方法查找  

bf 时间复杂度是O(n*m) 子串从头查找与串中原来与自己匹配的项如果匹配  就继续查找 如果 失配(不匹配)则返回到i(第一个匹配的字符)下一个(大概如下图)

优点 简单 缺点 时间复杂度比较大

代码如下

int BF(const char *str,const char *sub,int pos)//O(n*m){if(pos < 0){return -1;}int lenstr = strlen(str);int lensub = strlen(sub);int i = pos;int j = 0;while(i<lenstr && j<lensub){if(str[i] == sub[j]){i++;j++;}else{i = i-j+1;//失配,退到i原来的位置的下一个j = 0;}}if(j >= lensub)//找到了{return i-j;}else{return -1;}}

KMP 优点:时间复杂度比较小O(n+m)缺点:比较复杂

要先知道子串的k和j  k==j  k和j是相等长度相等字符的两个字符串k从头开始找 j从子串失配前开始找

找k和j大概如下图


算法sub[j]==sub[k(j从1 开始j+1《lenstr k从0开始)]|| k=-1  k=k+1  继续

else k=next【k】继续

代码如下

static void GetNext(const char*sub,int *next){int lensub = strlen(sub);next[0] = -1;next[1] = 0;int j = 1;//通过j求j+1的值int k = 0;while(j+1<lensub){if(k==-1 || sub[j]==sub[k]){next[++j] = ++k;//next[j]=k;++j;++k;}else{k = next[k];//}}}//KMP 算法特点:i不回退,时间复杂度O(n+m)int KMP(const char *str,const char *sub,int pos)//O(n+m){if(pos < 0){return -1;}int lenstr = strlen(str);int lensub = strlen(sub);int i = pos;int j = 0;int *next = (int *)malloc(lensub*sizeof(int));GetNext(sub,next);while(i<lenstr && j<lensub){if(j==-1 || (str[i]==sub[j])){i++;j++;}else//i不回退,j退到next[j](即k位置){j = next[j];}}free(next);if(j >= lensub)//找到了{return i-j;}else{return -1;}}


KMP 获取next【i】(即k值)str[i]==sub[j])继续

else   子串的j退回之前k的位置 再继续



原创粉丝点击