Kmp算法浅谈
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算法浅谈的更多相关文章
- Sunday算法浅谈
一.Sunday算法简介 Sunday算法在我看来比起Kmp和bm都更加容易理解,代码实现也更加简洁.Sunday算法由Daniel M.Sunday在1990年提出,它的思想跟BM算法很相似只不过S ...
- [算法]浅谈求n范围以内的质数(素数)
汗颜,数学符号表达今天才学会呀-_-# 下面是百度百科对质数的定义 质数(prime number)又称素数,有无限个. 质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数. 求质数的方法 ...
- Pollard Rho算法浅谈
Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机 ...
- 算法浅谈之DP悬线法
悬线法 用途 解决给定矩阵中满足条件的最大子矩阵 做法 用一条线(横竖貌似都行)左右移动直到不满足约束条件或者到达边界 定义 \(left[i][j]\):代表从\((i,j)\)能到达的最左位置 \ ...
- 浅谈URLEncoder编码算法
一.为什么要用URLEncoder 客户端在进行网页请求的时候,网址中可能会包含非ASCII码形式的内容,比如中文. 而直接把中文放到网址中请求是不允许的,所以需要用URLEncoder编码地址, 将 ...
- 浅谈Hex编码算法
一.什么是Hex 将每一个字节表示的十六进制表示的内容,用字符串来显示. 二.作用 将不可见的,复杂的字节数组数据,转换为可显示的字符串数据 类似于Base64编码算法 区别:Base64将三个字节转 ...
- 浅谈Base64编码算法
一.什么是编码解码 编码:利用特定的算法,对原始内容进行处理,生成运算后的内容,形成另一种数据的表现形式,可以根据算法,再还原回来,这种操作称之为编码. 解码:利用编码使用的算法的逆运算,对经过编码的 ...
- 浅谈大型web系统架构
动态应用,是相对于网站静态内容而言,是指以c/c++.php.Java.perl..net等服务器端语言开发的网络应用软件,比如论坛.网络相册.交友.BLOG等常见应用.动态应用系统通常与数据库系统. ...
- SDUT OJ 数据结构实验之串一:KMP简单应用 && 浅谈对看毛片算法的理解
数据结构实验之串一:KMP简单应用 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...
随机推荐
- docker镜像相关的常用操作
1.保存镜像 #docker save 镜像名称 -o 保存的完整地址和文件名 docker save zhoushiya/zhiboyuan -o d:/zhiboyuan.tar 2.载入镜像 # ...
- 高级特征工程I
Mean encodings 以下是Coursera上的How to Win a Data Science Competition: Learn from Top Kagglers课程笔记. 学习目标 ...
- setUserData
node.setUserData();//设置每个节点的datanode.getUserData();
- python:文件读写
#!/usr/bin/python# -*- coding:utf-8 -*- #!/usr/bin/python# -*- coding:utf-8 -*- file1 = open('a.txt' ...
- git的分支
git branch : git branch -r #查看远程分支 git branch -a #查看本地分支和远程分支 git branch -v #查看本地库的所有分支 git br ...
- CentOS7.0安装EMQ代理服务
CentOS7.0安装EMQ代理服务 安装文件下载 官网 : https://www.emqx.io/cn/ 下载地址: https://www.emqx.io/cn/downloads 选择需要的版 ...
- DTU DeepLearning: exercise 7
torch activation functions: sigmoid, relu, tanh, softplus. https://morvanzhou.github.io/tutorials/ma ...
- 【转载】Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别
转自:http://www.linuxidc.com/Linux/2014-03/98978.htm Pig 一种操作hadoop的轻量级脚本语言,最初又雅虎公司推出,不过现在正在走下坡路了.当初雅虎 ...
- JVM的前世今生
前世 jvm的数据区 分别是方法区(Method Area),Java栈(Java stack),本地方法栈(Native Method Stack),堆(Heap),程序计数器(Program Co ...
- Mysql5.6基础命令
Centos7下mysql5.6数据库的操作 Mysql如何修改密码? 1.使用mysqladmin修改,这种修改方式需要知道mysql的原始密码 修改密码后我们测试下看看能不能登录成功 怎么才能不需 ...