字符串朴素模式匹配算法的2种实现:

//1.朴素的模式匹配算法,用while实现

int StrStr_While(const char* pStr, const char* pSub, int* pos)
{
int nRet = 0;
int pStrLen = strlen(pStr);
int pSubLen = strlen(pSub);
int i = 0, j = 0;
int nLen = pStrLen - pSubLen; if (pStr == NULL || pSub == NULL)
{
nRet = -1;
printf("param input error!");
return nRet;
} while (i < pStrLen && j < pSubLen)
{
if (*(pStr + i) == *(pSub + j))
{
++i;
++j;
}
else
{
i = i - j + 1;
j = 0;
}
} if (j == pSubLen)
*pos = i - j + 1; return nRet;
}

//2.朴素的模式匹配,用for循环实现

int StrStr_For(const char* pStr, const char* pSub, int* pos)
{
int nRet = 0;
int pStrLen = strlen(pStr);
int pSubLen = strlen(pSub);
int i = 0, j = 0;
int nLen = pStrLen - pSubLen; if (pStr == NULL || pSub == NULL)
{
nRet = -1;
printf("param input error!");
return nRet;
} for (i = 0; i <= nLen; ++i)
{
for (j = 0; j < pSubLen; ++j)
{
if (*(pStr + i + j) != *(pSub + j))
break;
} if (j == pSubLen)
{
*pos = i + 1;
break;
}
} return nRet;
}

实现字符串的匹配有高效的算法。那就是KMP算法,实现例如以下:

//取得KMP算法须要用的的next数组

int GetNext(const char* pStr, int nNext[])
{
int nRet = 0;
if (pStr == NULL || nNext == NULL)
{
nRet = -1;
printf("param input error!\n");
return nRet;
} int nLen = strlen(pStr);
int i = 0, j = -1;
nNext[i] = j;
while (i < nLen - 1)
{
if (j == -1 || pStr[i] == pStr[j])
{
++i;
++j;
nNext[i] = j;
}
else
{
j = nNext[j];
}
} return nRet;
} //取next数组的改进型算法!剔除多个反复字符的next数组值持续增长。 int GetNextVal(const char* pStr, int nNext[]) { int nRet = 0; if (pStr == NULL || nNext == NULL) { nRet = -1; printf("param input error!\n"); return nRet; } int nLen = strlen(pStr); int i = 0, j = -1; nNext[i] = j; while (i < nLen - 1) { if (j == -1 || pStr[i] == pStr[j]) { ++i; ++j; if (pStr[i] != pStr[j]) nNext[i] = j; else nNext[i] = nNext[j]; } else { j = nNext[j]; } } return nRet; }

这是针对类似aaaaaaab这种字符串使用上面两个函数取得的next数组值得比較。注意书上的都是字符串从数组的下标为1的位置開始存储的。我改进的算法是还是让字符串从数组下标为0的位置開始存储。

所以上面的next数组值都要相较与原来的值减1。

//调用上面的函数实现KMP高效字符串模式匹配算法!

int Index_KMP(const char* pStr, const char* pSub, int* nPos)
{
int nRet = 0;
if (pStr == NULL || pSub == NULL || nPos == NULL)
{
nRet = -1;
printf("param input error!\n");
return nRet;
} int pStrlen = strlen(pStr);
int pSublen = strlen(pSub); int nNext[255] = { 0 };
//nRet = GetNext(pSub,nNext);
nRet = GetNextVal(pSub, nNext);
if (nRet != 0)
{
printf("call GetNext() func is error!\n");
return nRet;
} int i = 0, j = 0;
while (i < pStrlen && j < pSublen)
{
if (j == -1 || *(pStr + i) == *(pSub + j))
{
++i;
++j;
}
else
{
j = nNext[j];
}
} if (j == pSublen)
*nPos = i - j + 1; return nRet;
}

模式匹配KMP的更多相关文章

  1. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

  2. 『字符串模式匹配 KMP』

    字符串模式匹配 我们要先了解一下问题是什么. 模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配. KMP 然后我们来认识一下今天的主 ...

  3. 字符串模式匹配——KMP算法

    KMP算法匹配字符串 朴素匹配算法   字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就 ...

  4. 模式匹配KMP算法

    关于KMP算法的原理网上有很详细的解释,我试着总结理解一下: KMP算法是什么 以这张图片为例子 匹配到j=5时失效了,BF算法里我们会使i=1,j=0,再看s的第i位开始能不能匹配,而KMP算法接下 ...

  5. 模式匹配-KMP算法

    /***字符串匹配算法***/ #include<cstring> #include<iostream> using namespace std; #define OK 1 # ...

  6. 数据结构4.3_字符串模式匹配——KMP算法详解

    next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...

  7. KMP及其改进算法

    本文主要讲述KMP已经KMP的一种改进方法.若发现不正确的地方,欢迎交流指出,谢谢! KMP算法的基本思想: KMP的算法流程: 每当一趟匹配过程中出现字符比较不等时,不需回溯 i 指针,而是利用已经 ...

  8. acm算法模板(1)

    1. 几何 4 1.1 注意 4 1.2 几何公式 4 1.3 多边形 6 1.4 多边形切割 9 1.5 浮点函数 10 1.6 面积 15 1.7 球面 16 1.8 三角形 17 1.9 三维几 ...

  9. ACM-ICPC竞赛模板

    为了方便打印,不再将代码放到代码编辑器里,祝你好运. ACM-ICPC竞赛模板(1) 1. 几何 4 1.1 注意 4 1.2 几何公式 4 1.3 多边形 6 1.4 多边形切割 9 1.5 浮点函 ...

随机推荐

  1. HDU 2673 shǎ崽 OrOrOrOrz

    #include <cstdio> #include <algorithm> using namespace std; int main() { int n; while (s ...

  2. maven 添加自己的包

    mvn install:install-file -Dfile=d:/flea.jar -DgroupId=com.flea.bussiness -DartifactId=flea -Dversion ...

  3. Android项目导入时,出现的Could not write file 。。。。。。.classpath错误解决办法

    导入到Eclipse中后选择了相应的API后,红叉的项目错误没有了. 工程列表也无任何错误了.但出现了这样的提示框错误 说明的是.classpath这个环境文件不能写.随后,查看工程文件主目录下的.c ...

  4. Matlab pivotgolf

    function scoreout = pivotgolf(course,pivotstrat) % PIVOTGOLF Pivot Pickin' Golf. % Your goal is to u ...

  5. 跨域引入iframe 自适应高度

    最近和别的公司合作一个项目,需要从他们那边引入一个页面,刚开始想的挺简单的,用iframe 引入就好啦,可是操作中才发现,自适应的问题不好解决,试了挺多办法,最终找到一个比较好的方法,记录一下,留着备 ...

  6. 3.3 用NPOI操作EXCEL--生成一张工资单

    这一节,我们将综合NPOI的常用功能(包括创建和填充单元格.合并单元格.设置单元格样式和利用公式),做一个工资单的实例.先看创建标题行的代码: //写标题文本 HSSFSheet sheet1 = h ...

  7. 【JAVA】使用Eclipse依赖生成jar包时,避免最外层同时生成资源文件的配置。

    使用Eclipse依赖生成jar包时,如果做配置,生成的jar包文件会全部生成在外面,这并不是我们需要的,下面我们一起来修改下配置,使生成的jar包符合我们的需求吧. 1.如果不做任何配置生成的jar ...

  8. Nginx 之四: Nginx服务器的压缩功能和缓存功能

    在Nginx服务器配置文件中可以通过配置Gzip的使用,可以配置在http块,server 块或者location块中设置,Nginx服务器可以通过ngx_http_gzip_module模块.ngx ...

  9. XML 反序列化为Model

    什么也不多说,直接贴代码 需要反序列的XML <?xml version='1.0' encoding='utf-8' ?> <GetCitiesListResponse> & ...

  10. oracle 10g函数大全--分析函数

    oracle分析函数--SQL*PLUS环境 一.总体介绍 12.1 分析函数如何工作 语法 FUNCTION_NAME(<参数>,…) OVER (<PARTITION BY 表达 ...