子串在主串中的定位操作通常称做串的模式匹配。

KMP模式匹配算法实现:
/* Index_KMP.h头文件 */
#include<string>
#include<sstream> void get_next(std::string T,int *next)
{
unsigned int i,j;
i=1;
j=0;
next[1]=0;
while(i<(T.size()-1)) /* 此处T的首个字符T[0]表示串T的长度,不参与计算 */
{
if(j==0||T[i]==T[j]) /* T[i]表示后缀的单个字符,T[j]表示前缀的单个字符 */
{
++i;
++j;
next[i]=j;
}
else
j=next[j]; /* 若字符不相同,则j值回溯 */
}
} int Index_KMP(std::string S, std::string T, unsigned int pos)
{
std::string s,t; /*在字符串S,T的最前插入一个字符来保存串的长度值,*/
std::ostringstream s1,s2; /*用来保证字符串的有用元素是从下标1开始*/
s1<<S.size()<<S; /*将新的数组保存为s,t*/
s2<<T.size()<<T;
s=s1.str();
t=s2.str();
unsigned int i=pos; /* i用于主串s当前位置下标值,若pos不为1,则从pos位置开始匹配 */
unsigned int j=1; /* j用于字串t中当前位置下标值 */
int next[255]; /* 定义一next数组 */
get_next(t,next); /* 对串t作分析,得到next数组 */
while (i<=(s.size()-1) && j<=(t.size()-1)) /* 若i小于S的长度且j小于T的长度时,循环继续 */
{
if ( j==0 || s[i]==t[j]) /* 两字母相等则继续,相对于朴素算法增加了j=0判断 */
{
++i;
++j;
}
else /* 指针后退重新开始匹配 */
{
j=next[j]; /* j退回合适的位置,i值不变 */
}
}
if ( j>(t.size()-1) )
return i-(t.size()-1);
else
return 0;
}

KMP模式匹配算法的改进:


/* Index_KMP.h头文件 */
#include<string>
#include<sstream> void get_nextval(std::string T,int *nextval)
{
unsigned int i,j;
i=1;
j=0;
nextval[1]=0;
while(i<(T.size()-1)) /* 此处T的首个字符T[0]表示串T的长度,不参与计算 */
{
if(j==0||T[i]==T[j]) /* T[i]表示后缀的单个字符,T[j]表示前缀的单个字符 */
{
++i;
++j;
if (T[i]!=T[j]) /*若当前字符与前缀字符不同*/
nextval[i]=j; /*则当前的j为nextval在i位置的值*/
else
nextval[i]=nextval[j]; /*如果与前缀字符相同,则将前缀字符的nextval值赋值给nextval在i位置的值*/ }
else
j=nextval[j]; /* 若字符不相同,则j值回溯 */
}
} int Index_KMP(std::string S, std::string T, unsigned int pos)
{
std::string s,t; /*在字符串S,T的最前插入一个字符来保存串的长度值,*/
std::ostringstream s1,s2; /*用来保证字符串的有用元素是从下标1开始*/
s1<<S.size()<<S; /*将新的数组保存为s,t*/
s2<<T.size()<<T;
s=s1.str();
t=s2.str();
unsigned int i=pos; /* i用于主串s当前位置下标值,若pos不为1,则从pos位置开始匹配 */
unsigned int j=1; /* j用于字串t中当前位置下标值 */
int next[255]; /* 定义一next数组 */
get_nextval(t,next);
while (i<=(s.size()-1) && j<=(t.size()-1)) /* 若i小于S的长度且j小于T的长度时,循环继续 */
{
if ( j==0 || s[i]==t[j]) /* 两字母相等则继续,相对于朴素算法增加了j=0判断 */
{
++i;
++j;
}
else /* 指针后退重新开始匹配 */
{
j=next[j]; /* j退回合适的位置,i值不变 */
}
}
if ( j>(t.size()-1) )
return i-(t.size()-1);
else
return 0;
}

匹配算法不做变化,只需要将"get_next(T,next)"改为“get_nextval (T,next)”即可。



总结:改进过的KMP算法,它是在计算出 next 值的同时,如果a位字符与它 next 值指向的 b 位字符相等,则该 a 位的nextval 就指向 b 位的 nextval 值,如果不等,则该 a 位的 nextval 值就是它自己 a 位的 nextval 的值。

C++编程练习(7)----“KMP模式匹配算法“字符串匹配的更多相关文章

  1. 线性表-串:KMP模式匹配算法

    一.简单模式匹配算法(略,逐字符比较即可) 二.KMP模式匹配算法 next数组:j为字符序号,从1开始. (1)当j=1时,next=0: (2)当存在前缀=后缀情况,next=相同字符数+1: ( ...

  2. 详细解读KMP模式匹配算法

    转载请注明出处:http://blog.csdn.net/fightlei/article/details/52712461 首先我们需要了解什么是模式匹配? 子串定位运算又称为模式匹配(Patter ...

  3. [从今天开始修炼数据结构]串、KMP模式匹配算法

    [从今天开始修炼数据结构]基本概念 [从今天开始修炼数据结构]线性表及其实现以及实现有Itertor的ArrayList和LinkedList [从今天开始修炼数据结构]栈.斐波那契数列.逆波兰四则运 ...

  4. 串、KMP模式匹配算法

    串是由0个或者多个字符组成的有限序列,又名叫字符串. 串的比较: 串的比较是通过组成串的字符之间的编码来进行的,而字符的编码指的是字符在对应字符集中的序号. 计算机中常用的ASCII编码,由8位二进制 ...

  5. KMP模式匹配算法

    KMP模式匹配算法 相信很多人对于这个还有点不了解,或者说是不懂,下面,通过一道题,来解决软考中的这个问题! 正题: aaabaaa,其next函数值为多少? 对于这个问题,我们应该怎么做呢? 1.整 ...

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

    朴素的模式匹配算法(C++) 朴素的模式匹配算法,暴力,容易理解 #include<iostream> using namespace std; int main() { string m ...

  7. 数据结构(三)串---KMP模式匹配算法

    (一)定义 由于BF模式匹配算法的低效(有太多不必要的回溯和匹配),于是某三个前辈发表了一个模式匹配算法,可以大大避免重复遍历的情况,称之为克努特-莫里斯-普拉特算法,简称KMP算法 (二)KMP算法 ...

  8. 浅谈KMP模式匹配算法

    普通的模式匹配算法(BF算法) 子串的定位操作通常称为模式匹配算法 假设有一个需求,需要我们从串"a b a b c a b c a c b a b"中,寻找内容为"a ...

  9. 初探—KMP模式匹配算法

    KMP算法思想: 普通的字符串匹配算法S主串必须要回溯.但回溯就影响了效率. 改进的地方也就是这里,我们从P 串本身出发,事先就找准了T自身前后部分匹配的位置,那就可以改进算法. next数组的含义: ...

随机推荐

  1. ZOJ 3946 Highway Project

    1.迪杰斯特拉最小堆 #include<cstdio> #include<cstring> #include<cmath> #include<map> ...

  2. seajs的常用api简易文档

    目前使用sea.js的公司越来越多, 比如朋友网,阿里巴巴,淘宝网,百姓网,支付宝,有道云笔记等.模块化的javascript开发带来了可维护,可扩展性,尤其在多人协作开发的时候不用再担心文件依赖和函 ...

  3. CollapsingToolbarLayout学习笔记

    CollapsingToolbarLayout包裹 Toolbar 的时候提供一个可折叠的 Toolbar,一般作为AppbarLayout的子视图使用. <?xml version=" ...

  4. Apache处理请求步骤及过程

    Apache请求处理循环详解 : 1.Post-Read-Request阶段: 在正常请求处理流程中,这是模块可以插入钩子的第一个阶段.对于那些想很早进入处理请求的模块来说,这个阶段可以被利用. 2. ...

  5. Linux cronolog

    1. 关于本文    本文将以cronolog 1.6.2.apache 2.2.6为例,以CentOS 5为平台,讲述cronolog的安装和设置. 2. 关于cronolog     cronol ...

  6. ABP架构解析

    ABP总体介绍 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...

  7. Java-设计模式-单例模式-饿汉模式、懒汉模式

    //-------------------------------------------------------------饿汉模式--开始----------------------------- ...

  8. bzoj1070————2016——3——14

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1070: 题目概括: Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中 ...

  9. eclipse 工具栏修改

    本来和同学约好一起去吃饭的,刚电话说有亲戚过来了,叫我一起去吃 哪有那个闲心,去陪他们吃饭 刚好,把这个一起写了 相信很多人会很烦,eclipse的工具栏太多了,折了一行下来,看着不好看,还烦(本人觉 ...

  10. Windows与Linux文件系统互访的几种方法

    首先,我们知道基于文件的几种服务:ftp,sftp,这两种服务都是文件传输服务,偏重于网络传输,并不是实时互访.通常,我们需要在远程和本地 同时操作同一个目录,如:在Windows下使用各种强大的ID ...