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数组

首先上个代码

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

三.Kmp算法代码

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

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

四.整个程序完整代码

  1. #include <stdio.h>
  2. #include <string.h>
  3. void Getnext(int next[],char *MyString);
  4. int Kmp(char *T,int numt,char *P,int nump,int *next);
  5. const int SIZE=;
  6. int main()
  7. {
  8. char *T=new char[SIZE];
  9. char *P=new char [SIZE];
  10. int *next=new int [SIZE];
  11. scanf("%s",T);
  12. scanf("%s",P);
  13. Getnext(next,P);
  14. for(int i=;i<strlen(P);i++) printf("%d,",next[i]);
  15. printf("\n%d",Kmp(T,strlen(T),P,strlen(P),next));
  16. return ;
  17. }
  18. void Getnext(int next[],char *MyString)
  19. {
  20. int j=,k=-;
  21. next[]=-;
  22. while(j<strlen(MyString)-)
  23. {
  24. if(k == - || MyString[j] == MyString[k])next[++j] = ++k;
  25. else k = next[k];
  26. }
  27. }
  28. int Kmp(char *T,int numt,char *P,int nump,int *next)//T为主串,P为模式串
  29. {
  30. int i=,j=;//i为主串的指针,j为模式串的指针
  31. while(i<=numt-nump)
  32. {
  33. while((T[i]==P[j]&&i<numt)||j==-) ++i,++j;
  34. if(j==nump)//找到匹配串
  35. return i-nump;//返回在主串中的起始位置
  36. j=next[j];
  37. }
  38. return -;//表示无法找到
  39. }
  1.  

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. docker 免sudo设置(仅3个命令)

    首先,下载docker, 需3话: sudo apt install docker.io sudo systemctl start docker sudo systemctl enable docke ...

  2. go语言 实现哈希算法

    验证结果网址 http://www.fileformat.info/tool/hash.htm "golang.org/x/crypto/md4"不存在时,解决方法: cd $GO ...

  3. 《NVMe-over-Fabrics-1_0a-2018.07.23-Ratified》阅读笔记(3)-- 命令

    3 命令 Fabrics命令用于创建队列和初始化controller.Fabrics命令的Opcode字段填写0x7F.无论controller是否处于使能状态(CC.EN)Fabrics命令都会被处 ...

  4. PolandBall and Forest

    PolandBall lives in a forest with his family. There are some trees in the forest. Trees are undirect ...

  5. OSS上传文件时设置请求头

    直接上传: // 如果需要上传时设置存储类型与访问权限,请参考以下示例代码. // ObjectMetadata metadata = new ObjectMetadata(); // metadat ...

  6. VMware上Linux虚拟机和Windows共享文件夹

    参考文章:https://blog.csdn.net/qq_19004627/article/details/78689641 操作环境:主机:Windows10,VMware Workstation ...

  7. leetcode 198 House Robber I

    function rob(nums) { if(!nums || nums.length === 0) { return 0; } else if(nums.length < 2){ retur ...

  8. python之路之线程,进程,协程

    一.线程和进程概述 1.python线程的Event 2.python线程其他和队列以及生产者消费者 3. 使用multprocessing创建进程 4.进程间数据共享方式——sharedmeory( ...

  9. C++-HDU1000,1001,1002-格式是真的坑

    #include <cstdio> int main(){ for(int a,b;~scanf("%d%d",&a,&b);printf(" ...

  10. java判断相等

    一.字符串 1.equals():比较内容,推荐 String a=new String("abc"); String b=new String("abc"); ...