KMP字符串查找
来源:互联网 发布:数据中心的网络交换机 编辑:程序博客网 时间:2024/05/21 07:59
KMP算法
KMP字符串查找算法的目的是减少不必要的比较次数,举个简单的例子,从字符串A:"abcdeabcdfg"中查找字符串B:"abcdf"。
使用普通的查找法查找字符串的步骤是这样的:
先拿A[0:4]分别与B对应位置的字母比较,如果不相等则拿A[1:5]与B比较,依次类推,直到结束。
而KMP算法先分析要朝朝的字符串,以B为例,由于a与后面的四个字节都不相同,而在比较A[0:4]与B时在A[4]处发生不匹配现象,所以,再拿A[1:5]、A[2:6]、A[3:7]分别与B比较是没有意义的,直接比较A[4:8]与B即可。这样就省掉了几次循环。
KMP算法在分析检索关键词时需要考虑的问题还有很多,这里就不一一分析了,下面是C实现的代码:
优化KMP算法
为了更大限度的减少重复匹配次数,还可以对KMP算法进行优化,优化步骤非常简单,下面是优化后的代码,新增的代码后都标有line开头的注释:
其实,理解起来也比较简单,对于检索关键词K:"ababa"这种情况,假设外层循环计数变量为i,如果在K[0]处发生不匹配,则下次循环前i应该自加,重新与K进行比较,而如果在K[1]处发生不匹配时,则下次循环前,i无需自加,直接与K进行比较,但是如果在K[2]处发生不匹配时,则下次循环前,i应该自加然后与K进行匹配,因为K[2]跟K[0]相等,K[2]与之不匹配则K[0]也与之不匹配,所以i需要自加,从后一个元素开始比较。
本文链接:http://blog.csdn.net/girlkoo/article/details/17435557
本文作者:girlkoo
KMP字符串查找算法的目的是减少不必要的比较次数,举个简单的例子,从字符串A:"abcdeabcdfg"中查找字符串B:"abcdf"。
使用普通的查找法查找字符串的步骤是这样的:
先拿A[0:4]分别与B对应位置的字母比较,如果不相等则拿A[1:5]与B比较,依次类推,直到结束。
而KMP算法先分析要朝朝的字符串,以B为例,由于a与后面的四个字节都不相同,而在比较A[0:4]与B时在A[4]处发生不匹配现象,所以,再拿A[1:5]、A[2:6]、A[3:7]分别与B比较是没有意义的,直接比较A[4:8]与B即可。这样就省掉了几次循环。
KMP算法在分析检索关键词时需要考虑的问题还有很多,这里就不一一分析了,下面是C实现的代码:
#include <stdio.h>#include <stdlib.h>#include <string.h>void getNext( char* keyword, char* next){ int i = 0, j = -1; next[0] = -1; int end_pos = strlen(keyword)-1; while(i < end_pos){ if(j == -1 || keyword[j] == keyword[i]){ ++ i; ++ j; next[i] = j; } else{ j = next[j]; } }}int find( char *string, char *keyword){ int i = 0, j = 0, len = strlen(string), klen = strlen(keyword); char *next = (char*)malloc( strlen(keyword)); getNext(keyword, next); while(i < len && j < klen){ if(j == -1 || string[i] == keyword[j]){ ++i; ++j; } else{ j = next[j]; } } free(next); if(j == klen){ return i-klen; } else{ return -1; }}int main(){ char *keyword = "abcdef"; char next[strlen(keyword)]; getNext(keyword, next); int i; int len = strlen(keyword); printf("next:" ); for(i = 0; i != len; ++i){ printf("%d" , next[i]); } printf("\n" ); int pos = find("adadababcdefcf", keyword); printf(" pos = %d\n", pos); return 0;}
优化KMP算法
为了更大限度的减少重复匹配次数,还可以对KMP算法进行优化,优化步骤非常简单,下面是优化后的代码,新增的代码后都标有line开头的注释:
#include <stdio.h>#include <stdlib.h>#include <string.h>void getNext( char* keyword, char* next){ int i = 0, j = -1; next[0] = -1; int end_pos = strlen(keyword)-1; while(i < end_pos){ if(j == -1 || keyword[j] == keyword[i]){ ++ i; ++ j; if(keyword[j] == keyword[i]){ // line 1 next[i] = next[j]; // line 2 } // line 3 else{ // line 4 next[i] = j; // line 5 } // line 6 } else{ j = next[j]; } }}int find( char *string, char *keyword){ int i = 0, j = 0, len = strlen(string), klen = strlen(keyword); char *next = (char*)malloc( strlen(keyword)); getNext(keyword, next); while(i < len && j < klen){ if(j == -1 || string[i] == keyword[j]){ ++i; ++j; } else{ j = next[j]; } } free(next); if(j == klen){ return i-klen; } else{ return -1; }}int main(){ char *keyword = "ababa"; char next[strlen(keyword)]; getNext(keyword, next); int i; int len = strlen(keyword); printf("next:" ); for(i = 0; i != len; ++i){ printf("%d" , next[i]); } printf("\n" ); int pos = find("abasbabababababababababab", keyword); printf("pos = %d\n", pos); return 0;}
其实,理解起来也比较简单,对于检索关键词K:"ababa"这种情况,假设外层循环计数变量为i,如果在K[0]处发生不匹配,则下次循环前i应该自加,重新与K进行比较,而如果在K[1]处发生不匹配时,则下次循环前,i无需自加,直接与K进行比较,但是如果在K[2]处发生不匹配时,则下次循环前,i应该自加然后与K进行匹配,因为K[2]跟K[0]相等,K[2]与之不匹配则K[0]也与之不匹配,所以i需要自加,从后一个元素开始比较。
本文链接:http://blog.csdn.net/girlkoo/article/details/17435557
本文作者:girlkoo
0 0
- KMP字符串查找
- KMP算法查找字符串
- 字符串查找之KMP
- KMP字符串查找算法
- KMP 字符串查找
- KMP字符串查找
- KMP字符串查找算法
- 字符串查找算法-KMP
- KMP - 字符串查找算法
- 字符串查找算法kmp
- 字符串查找算法kmp
- KMP字符串查找算法
- KMP快速查找字符串
- KMP字符串查找算法
- 字符串查找-bf kmp
- 查找字符串之 KMP算法
- KMP子字符串查找算法
- 字符串的查找--KMP算法
- jar包下载
- C#+JS 弹出详细信息遮罩层(适合Repeater DataList GridView)
- 【leetcode Java】二叉树的递归遍历以及最大深度的求解(Java)
- 转:高性能、高流量Java Web站点打造的22条建议
- Life 程序员编程语录
- KMP字符串查找
- UICollectionView的简单使用
- unix,solaris解压tar.gz
- C++ operator两种用法
- ORACLE 10.2.0.5 RAC FOR RedHat Linux AS5 (X86) 实施手册
- 通过异常了解Weblogic下tld文件的验证
- 最大公约数和最小公倍数 递归算法
- 那些逝去的岁月-档案
- 如何消除matlAB启动时的Warning:Name is nonexistent or not a directory ...