【字符串匹配】KMP算法和next数组的c/c++实现
KMP算法基本思想有许多博客都写到了,写得也十分形象,不懂得可以参考下面的传送门,我就不解释基本思想了。本文主要给出KMP算法及next数组的计算方法(主要是很多网上的代码本人(相信应该是许多人吧)看不懂,直接拿来用也是各种问题),这里的代码封装性和优化都有待考究,但是基本能实现KMP算法
http://www.cnblogs.com/c-cloud/p/3224788.html
这里提醒各位看官,while循环次数不是常见的固定次数的循环,而是动态根据实际情况将大家固认为的“一趟循环”分解成几次,看代码时留意这点,对各位看官应该有所帮助。
1.KMP的next数组生成方法。
根据链接中的15来看,可以根据搜索的字符串strKey的长度确定分析的次数(第一次显然是0),第1-len次分析的长度刚好就是左边字符个数(1-len),相应次数的前缀后最的共同元素的最长长度为对应next数组的值。
同时我们发现规律:根据前缀和后缀的特点,我们可以从每次分析的字符串(每次分析的字符串都不一样)的最后一个字符开始,向前进行字符匹配。
每次匹配成功一个字符就后缀索引backIndex-1;
每次匹配字符失败,需要判断是否已经有部分匹配的字符串,若有,应重置后缀索引backIndex=0,相应next数值为0;若无,前缀索引frontIndex+1即可
每趟大循环,如果遇到已经计算到next的相应数值则进入分析下一组(这里组的概念类似链接的第15点的分析步骤);若遇到该组没有分析完,但是遇到了一些情况:比如说frontIndex =0,或者匹配成功一个字符,则进入大循环,但是是继续分析还没有分析完的这组
void cal_next(char * strKey, int * next, int len)
{
int calTimes = ;//计算次数 ,第一次肯定为零
int frontIndex=;//负责在前缀里边索引元素
int backIndex = ;//负责在后缀里边索引元素
//清零
for (frontIndex = ; frontIndex < len; frontIndex++)
{
next[frontIndex] = ;
}
frontIndex = calTimes-;//取得可能的最大前缀和后缀的共同元素的最长的长度0-
backIndex = calTimes-;//0-
while (calTimes<=len)
{
printf("calTimes:%d\r\n",calTimes);
printf("frontIdex:%d\r\n", frontIndex);
printf("backIdex:%d\r\n", backIndex);
while (frontIndex > && strKey[backIndex] != strKey[frontIndex ])//最多calTimes次比较
{
printf(" There is a unmatched char\r\n");
if (next[calTimes - ] != )//已经有部分字符匹配,中途出现了不匹配的字符
{
next[calTimes-] = ;
backIndex = calTimes-;//重置后缀索引
break;
}
frontIndex--;
}
if (frontIndex == && strKey[backIndex ] != strKey[])//最差的情况,一次都没有匹配成功
{
next[calTimes-] =;
calTimes++;
frontIndex = calTimes-;
backIndex = calTimes-;
printf(" There is never matched\r\n");
}
else if (frontIndex == && strKey[backIndex ] == strKey[])//最后一个字符匹配成功
{
next[calTimes - ] +=;
calTimes++;
frontIndex = calTimes-;
backIndex = calTimes-;
printf(" the last char matched\r\n");
}
else
{
if (frontIndex > && strKey[backIndex ] == strKey[frontIndex ]) //匹配成功一个
{
next[calTimes - ]++;
backIndex -= ;
frontIndex--;
printf(" a char matched\r\n");
}
}
}
}
2.KMP算法的实现
这里的实现步骤其实就是算法了步骤了,应该没有什么可讲的,基本的实现思路跟next的生成方法差不多。
void kmp(char * strText, char *strKey)
{
int *next = new int[strlen(strKey)];
//计算next 数组
cal_next(strKey,next,strlen(strKey));
//查找
int textLenght = strlen(strText);
int keyLenght = strlen(strKey);
int textIndex = ;
int keyIndex = ;
int successNums = ;
while (textIndex < textLenght)
{
while (textIndex <textLenght && strKey[keyIndex] != strText[textIndex])
{
printf(" There is a unmatched char\r\n");
if (keyIndex != )//已经匹配部分字符中途遇到不匹配的字符
{
textIndex -= next[keyIndex-];
printf(" keyIndex %d next %c\r\n", keyIndex, strText[textIndex]);
keyIndex = ;
}else
textIndex++;
}
if (textIndex == textLenght )//一个都没有匹配成功(textLenght-1 时,一定是不予strKey的“相应字符匹配”,所以才会进入textIndex++)
{
if (successNums==)
printf(" Summary: Never Matched\r\n");
else printf(" Summary: %d Matched\r\n",successNums);
}
else if (strKey[keyIndex] == strText[textIndex])//找到匹配的字符
{
keyIndex++;
textIndex++;
if (keyIndex == keyLenght)
{
keyIndex = ;
successNums++;
printf(" Summary: Matched @textIndex=%d\r\n", textIndex - keyLenght);
}
printf(" There is a Matched Char\r\n");
}
}
}
3.main
int _tmain(int argc, _TCHAR* argv[])
{
char Search[] = {'a','b','\0'};
char Text[] = "abababdhello";
kmp(Text, Search); while ();
return ;
}
【字符串匹配】KMP算法和next数组的c/c++实现的更多相关文章
- 字符串匹配-BF算法和KMP算法
声明:图片及内容基于https://www.bilibili.com/video/av95949609 BF算法 原理分析 Brute Force 暴力算法 用来在主串中查找模式串是否存以及出现位置 ...
- 字符串匹配KMP算法中Next[]数组和Nextval[]数组求法
数据结构课本上给了这么一段算法求nextval9[]数组 int get_nextval(SString T,int &nextval[ ]) { //求模式串T的next函数修正值并存入数组 ...
- 字符串匹配KMP算法详解
1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有比较详细的通俗易懂的讲解,另一方面也怪自己没有沉下心来研究.最近在leetcode上又遇见字符串匹配的题目,以此 ...
- 字符串匹配-KMP
节选自 https://www.cnblogs.com/zhangtianq/p/5839909.html 字符串匹配 KMP O(m+n) O原来的暴力算法 当不匹配的时候 尽管之前文本串和模式串已 ...
- 字符串匹配--kmp算法原理整理
kmp算法原理:求出P0···Pi的最大相同前后缀长度k: 字符串匹配是计算机的基本任务之一.举例,字符串"BBC ABCDAB ABCDABCDABDE",里面是否包含另一个字符 ...
- 字符串匹配KMP算法的讲解C++
转自http://blog.csdn.net/starstar1992/article/details/54913261 也可以参考http://blog.csdn.net/liu940204/art ...
- zstu.4194: 字符串匹配(kmp入门题&& 心得)
4194: 字符串匹配 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 206 Solved: 78 Description 给你两个字符串A,B,请 ...
- 字符串匹配——KMP算法
关于KMP算法的分析,我觉得这两篇博客写的不错: http://www.ruanyifeng.com/blog/2013/05/Knuth–Morris–Pratt_algorithm.html ht ...
- 字符串匹配KMP算法的C语言实现
字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...
随机推荐
- Ruby安装Scss
Ruby安装Scss 引言 已经许久不写HTML了,今天有点以前的东西要改.但是刚装的Windows10,已经没有以前的Web开发环境了.只好重新安装. 结果Webstorm装好后配置Scss出现错误 ...
- 在Azure虚拟机上安装SQL server
Azure虽然向用户提供SQL paas服务,但是大多数用户还是习惯在用虚拟机自己搭建SQL server,这样的好处是便于后期最大化的扩展,所以鉴于这些情况,所以觉得有必要写这篇博客. 首先,我们要 ...
- Python购物车程序
1.要求用户输入工资,然后打印购物菜单 2.用户可以不断的购买商品,直到钱不够为止 3.退出时格式化打印用户已购买的商品和剩余金额 salary = int(input("请输入你的工资:& ...
- IIS部署遇到的一些问题
IIS部署时候会遇到一些具体的问题,记录一下.此处的部署环境为Windows Server 2012 64位版本 1.基本部署:角色和功能管理-->web服务器,勾选相应的服务与功能,然后安装即 ...
- client offset screen 的区别
clientX 设置或获取鼠标指针位置相对于窗口客户区域的 x 坐标,其中客户区域不包括窗口自身的控件和滚动条. clientY 设置或获取鼠标指针位置相对于窗口客户区域的 y 坐标,其中客户区域不包 ...
- php获取用户 地区 、ip地址
header("Content-type: text/html; charset=utf-8"); function getCity($ip = '')//获取地区 { if($i ...
- 【krpano】krpano xml资源解密(破解)软件说明与下载(v1.4)
欢迎加入qq群551278936讨论krpano技术以及获取最新软件. 该软件已经不再维护,现在已经被KRPano资源分析工具取代,详情参见 http://www.cnblogs.com/reac ...
- testng 失败自动截图
testng执行case failed ,testng Listener会捕获执行失败,如果要实现失败自动截图,需要重写Listener的onTestFailure方法 那么首先新建一个Listene ...
- PHP新手常见的一些不好习惯(抄的 有待理解)
1.不写注释(是个好习惯,不过也没必要每个语句都要写) 2.不使用可以提高生产效率的IDE工具 3.不使用版本控制 4.不按照编程规范写代码 5.不使用统一的方法 6.编码前不去思考和计划 7.在执行 ...
- struts2 No result defined for action XXX and result input
这种错误的原因一般是页面的属性和action里的属性个数.名称.类型不一致造成的 困扰了我一下午的问题,原来是表单中有两个input-text的name属性重复了,然后接受参数的时候就出现了这个错误 ...