Kmp算法浅谈

一.Kmp算法思想

在主串和模式串进行匹配时,利用next数组不改变主串的匹配指针而是改变模式串的匹配指针,减少大量的重复匹配时间。在Kmp算法中,next数组的构建是整个Kmp算法的核心所在。

二.Kmp核心之next数组的构建

(1)前缀,后缀的定义

(2)最长公共前后缀定义

(3)next数组的含义

next数组代表各个长度子串(这些字串的起始位置都为0)的最长公共前后缀长度,为了方便代码的编写next[0]定为-1,表示前0个字符根本不存在前后缀这一说法。其他的例如next[1]表示前一个字符的 最长公共前后缀 ,很明显根据前后缀的定义,next[1]=0;next[1]和next[0]在本博客说明的next数组构成中是唯一和确定的。

(4)最长公共前后缀定义及与next的联系

(5)对于一个模式串next数组到底能表示什么

首先根据上面的说法next数组表示了模式串长度为i的前缀的最长公共前后缀的的长度,所以说next可以来表示长度。这个时候我们在深究一下它表示的是谁的长度?它表示的是最长公共前后缀的!!!!,也就是说它可以表示模式串中第next[i]个元素的下标!!!,不懂的话看图就明白了

(6)如何利用next数组的性质避免重复匹配呢

三.如何用代码的形式得到next数组

首先上个代码

void Getnext(int next[],char *MyString)
{
int j=,k=-;
next[]=-;//规定,方便后面k的计算
while(j<strlen(MyString)-)//j不能超过整个串的长度
{
//j为当前字符,k为j前面那些字符的最长公共前后缀的下一个字符
if(k == - || MyString[j] == MyString[k])next[++j] = ++k;
//模式串的第一个字符就要比较的字符不一样,那我就要将模式串的下一个字符和我要比较的字符比较,且现在k还是为-1的,所以++j,++k
else k = next[k];
}
}
 

三.Kmp算法代码

得到了next后一切就简单了,无非就是设定两个“指针”分别指向主串和模式串,当出现不匹配时模式串的指针根据next数组移动就好了,直接上代码

int Kmp(char *T,int numt,char *P,int nump,int *next)//T为主串,P为模式串
{
int i=,j=;//i为主串的指针,j为模式串的指针
while(i<=numt-nump)
{
while((T[i]==P[j]&&i<numt)||j==-) ++i,++j;//j==-1
//模式串第一个就和主串中要匹配的字符不匹配,主串字符后移一位,模式串的指针也从-1恢复到零
if(j==nump)//找到匹配串
return i-nump;//返回在主串中的起始位置
j=next[j];
}
return -;//表示无法找到
}
 

四.整个程序完整代码

#include <stdio.h>
#include <string.h>
void Getnext(int next[],char *MyString);
int Kmp(char *T,int numt,char *P,int nump,int *next);
const int SIZE=;
int main()
{
char *T=new char[SIZE];
char *P=new char [SIZE];
int *next=new int [SIZE];
scanf("%s",T);
scanf("%s",P);
Getnext(next,P);
for(int i=;i<strlen(P);i++) printf("%d,",next[i]);
printf("\n%d",Kmp(T,strlen(T),P,strlen(P),next));
return ;
}
void Getnext(int next[],char *MyString)
{
int j=,k=-;
next[]=-;
while(j<strlen(MyString)-)
{
if(k == - || MyString[j] == MyString[k])next[++j] = ++k;
else k = next[k];
}
}
int Kmp(char *T,int numt,char *P,int nump,int *next)//T为主串,P为模式串
{
int i=,j=;//i为主串的指针,j为模式串的指针
while(i<=numt-nump)
{
while((T[i]==P[j]&&i<numt)||j==-) ++i,++j;
if(j==nump)//找到匹配串
return i-nump;//返回在主串中的起始位置
j=next[j];
}
return -;//表示无法找到
}
 

Kmp算法浅谈的更多相关文章

  1. Sunday算法浅谈

    一.Sunday算法简介 Sunday算法在我看来比起Kmp和bm都更加容易理解,代码实现也更加简洁.Sunday算法由Daniel M.Sunday在1990年提出,它的思想跟BM算法很相似只不过S ...

  2. [算法]浅谈求n范围以内的质数(素数)

    汗颜,数学符号表达今天才学会呀-_-# 下面是百度百科对质数的定义 质数(prime number)又称素数,有无限个. 质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数. 求质数的方法 ...

  3. Pollard Rho算法浅谈

    Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机 ...

  4. 算法浅谈之DP悬线法

    悬线法 用途 解决给定矩阵中满足条件的最大子矩阵 做法 用一条线(横竖貌似都行)左右移动直到不满足约束条件或者到达边界 定义 \(left[i][j]\):代表从\((i,j)\)能到达的最左位置 \ ...

  5. 浅谈URLEncoder编码算法

    一.为什么要用URLEncoder 客户端在进行网页请求的时候,网址中可能会包含非ASCII码形式的内容,比如中文. 而直接把中文放到网址中请求是不允许的,所以需要用URLEncoder编码地址, 将 ...

  6. 浅谈Hex编码算法

    一.什么是Hex 将每一个字节表示的十六进制表示的内容,用字符串来显示. 二.作用 将不可见的,复杂的字节数组数据,转换为可显示的字符串数据 类似于Base64编码算法 区别:Base64将三个字节转 ...

  7. 浅谈Base64编码算法

    一.什么是编码解码 编码:利用特定的算法,对原始内容进行处理,生成运算后的内容,形成另一种数据的表现形式,可以根据算法,再还原回来,这种操作称之为编码. 解码:利用编码使用的算法的逆运算,对经过编码的 ...

  8. 浅谈大型web系统架构

    动态应用,是相对于网站静态内容而言,是指以c/c++.php.Java.perl..net等服务器端语言开发的网络应用软件,比如论坛.网络相册.交友.BLOG等常见应用.动态应用系统通常与数据库系统. ...

  9. SDUT OJ 数据结构实验之串一:KMP简单应用 && 浅谈对看毛片算法的理解

    数据结构实验之串一:KMP简单应用 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...

随机推荐

  1. SPDK-nvmf与不同传输类型的公共接口

    SPDK-nvmf与不同传输类型的公共接口 不同类型的传输层到nvmf的公共命令请求接口 nvmf_fc_hwqp_handle_request() -->cmd_iu = buffer-> ...

  2. C语言注释符号

    同学们认为注释很简单,那我来看看下面的代码是否正确? 1.似是而非的问题 int main() { int/*...*/i; char* s = "abcdefgh //hijklmn&qu ...

  3. 解决无法将“babel”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。

    错误截图: 第一反应想到的是环境变量没有配置好,再仔细检查一下,并没有错误 在cmd窗口运行命令“ babel --version ”,如果出现对应的版本号,那就说明环境变量是正确的 解决方案: 用管 ...

  4. layui下拉框数据过万渲染渲染问题解决方案

    方案一:layui下拉框分页插件 https://fly.layui.com/jie/29002/ 此插件我用了下浏览器缓存有问题,而且当下拉框数据量过万后,会一直渲染不出来,期待后期作者优化 如图下 ...

  5. MVC5+EF6 入门完整教程2 :从前端UI开始

    MVC分离的比较好,开发顺序没有特别要求,先开发哪一部分都可以,这次我们主要讲解前端UI的部分. ASP.NET MVC抛弃了WebForm的一些特有的习惯,例如服务器端控件,ViewState这些东 ...

  6. onkeyup的死循环问题

    如果对一个控件调用的onkeyup事件,那么不能用回车来关闭alert()弹窗,因为按下回车的同时又再次触发了这个onkeyup事件,这样会造成一个死循环,不停按回车,不停的alert(), 所以应该 ...

  7. python的setup和teardown

    关于python unittest ① setup():每个测试函数运行前运行② teardown():每个测试函数运行完后执行③ setUpClass():必须使用@classmethod 装饰器, ...

  8. Rabbitmq consumer端超时报错

    0x01 应用场景: 使用rabbitmq的exchange模式,type为direct,消费端不需要向生产端返回结果no_ack=True 其中某个consumer任务耗时较长(5min以上),结果 ...

  9. Python小白的零碎记录

    1 3.7往后iterable .iterator包都包含在collections.abc中了,记录一下 from collections.abc import Iterable,Iterator p ...

  10. 【做题笔记】P1042 乒乓球

    坑 #1:输入有若干行,但处理的时候要看成一个整体的信息.比如说第一行最后一局比分是 2:1 ,这时不算比完,这个比分要继承到第二行的信息中继续处理. 坑 #2:一局结束,当且仅当其中一方比分大于等于 ...