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 免sudo设置(仅3个命令)
首先,下载docker, 需3话: sudo apt install docker.io sudo systemctl start docker sudo systemctl enable docke ...
- go语言 实现哈希算法
验证结果网址 http://www.fileformat.info/tool/hash.htm "golang.org/x/crypto/md4"不存在时,解决方法: cd $GO ...
- 《NVMe-over-Fabrics-1_0a-2018.07.23-Ratified》阅读笔记(3)-- 命令
3 命令 Fabrics命令用于创建队列和初始化controller.Fabrics命令的Opcode字段填写0x7F.无论controller是否处于使能状态(CC.EN)Fabrics命令都会被处 ...
- PolandBall and Forest
PolandBall lives in a forest with his family. There are some trees in the forest. Trees are undirect ...
- OSS上传文件时设置请求头
直接上传: // 如果需要上传时设置存储类型与访问权限,请参考以下示例代码. // ObjectMetadata metadata = new ObjectMetadata(); // metadat ...
- VMware上Linux虚拟机和Windows共享文件夹
参考文章:https://blog.csdn.net/qq_19004627/article/details/78689641 操作环境:主机:Windows10,VMware Workstation ...
- leetcode 198 House Robber I
function rob(nums) { if(!nums || nums.length === 0) { return 0; } else if(nums.length < 2){ retur ...
- python之路之线程,进程,协程
一.线程和进程概述 1.python线程的Event 2.python线程其他和队列以及生产者消费者 3. 使用multprocessing创建进程 4.进程间数据共享方式——sharedmeory( ...
- C++-HDU1000,1001,1002-格式是真的坑
#include <cstdio> int main(){ for(int a,b;~scanf("%d%d",&a,&b);printf(" ...
- java判断相等
一.字符串 1.equals():比较内容,推荐 String a=new String("abc"); String b=new String("abc"); ...