• 前缀和后缀的最大相等长度

为了更好的理解我接下来所说的回溯值的求法,这里先介绍一下,如何求一个字符串的前缀和后缀相等的最大长度,为了便于说明记为k。

注意:前缀和后缀不能为字符串本身!!!!!!

如字符串“abcab”的k为2、字符串“a”的k为0、“aaaaa”的k为4、“abcaabc”的k为3。

  • 回溯值

在主串T中寻找模式串P的过程称为模式匹配。若匹配成功,则返回P在T中的位置,匹配失败,返回0;常用的算法有两种,一个是朴素的模式匹配算法,这里就不做过多介绍。另一个就是看书看到头晕的KMP算法~~

这里首先来大概讲一讲KMP算法思想的关键在于那里,先通过图来看一下,KMP算法匹配的过程

上图:i=0,j=0;i=1,j=1;i=2,j=2时字符都是匹配的,当i取3,j取3的时候,字符不匹配,这时候,如果按朴素的模式匹配算法来求,这时候需要将i退回i=1处,j退回j=0处。但我们观察发现,j之前的字符串和主串中一部分已经完全匹配了,而“aba”的k(上一个标签中出现)为1,这时i不动,让j移到k处,即j=1;“aba”的前缀a已经和后缀a相等,而后缀a已经和主串中的a匹配了,所以这个时候已经不需要再匹配a。如下图:

以这样一个小小的例子我们可以发现,关键就是求得当p[j]与T[i]不匹配时,j应该退回到模式串的什么位置。模式串中每一个位置都有它对应的回溯值。这样一个和模式串下标有关的数组记为next[]。

手算快速求出next【】呢???

如“abaabcac”,默认当j=0时,next[0]=-1。

当j=1是,拿出他之前的子串,即“a”,k值为0,所以next[1]=0;

当j=2时,拿出他之前的子串,即“ab”,k为0,所以next[2]=0;

当j=3时,拿出他之前的子串,即“aba”,k为1,所以next[3]=1;

当j=4时,拿出他之前的子串,即“abaa”,k为1,所以next[4]=1;

当j=5时,拿出他之前子串,即“abaab”,k为2,所以next[5]=2;

当j=6时,拿出他之前子串,即“abaabc”,k为0,所以next[6]=0;

当j=7时,拿出他之前的子串,即“abaabca”,k为1,所以next[7]=1;

所以模式串P的失效值的数组为[-1,0,0,1,1,2,0,1];

  • 失效函数值的两种实现

  • 求模式失效函数值的递归算法

int getNext(int j,char p[]){if(j==0){return -1;}if(j>0){int k=getNext(j-1,p);while(k>=0){if(p[k]==p[j-1]){return k+1;}else{k=getNext(k,p);}}return 0;}return 0;
} 

求模式失效函数值的递推算法

void getNext(char p[],int next[]){int j=0;int k=-1;next[0]=-1;while(p[j]){if(k==-1||p[k]==p[j]){j++;k++;next[j]=k;}else{k=next[k];}}
}
  • 优化的递推算法

    void getNext(char p[],int nexval[]){int j=0,k=-1;nexval[j]=k;while(p[j]){if(k==-1||p[j]==p[k]){j++;k++;if(p[j]==p[k]){nexval[j]=nexval[k];}else{nexval[j]=k;}}else{k=nexval[k];}}
    }
  • 完整的KMP算法

    #include <iostream>
    #include <cstring>
    using namespace std;
    int getNext(int j,char P[]){ if(j==0){return -1;}while(P[j]){int k=getNext(j-1,P);while(k>=0){if(P[j-1]==P[k]){return k+1;}else{k=getNext(k,P);}}return 0;}return 0;
    }
    void getNext(char P[],int next[]){int j=0,k=-1;next[0]=-1;while(P[j]!='\0'){if(k==-1||P[j]==P[k]){j++;k++;next[j]=k;}else{k=next[k];}}return;
    }
    void getNextval(char P[],int nextval[]){int j=0,k=-1;while(P[j]!='\0'){if(k==-1||P[j]==P[k]){k++;j++;if(P[j]==P[k]){nextval[j]=nextval[k];}else{nextval[j]=k;}}else{k=nextval[k];}}
    }
    int kmpCheck(char T[],char P[],int index[]){int n=strlen(P);int next[n]; int k=0;getNext(P,next);int i=0,j=0;while(j==-1||T[i]&&P[j]){if(j==-1||T[i]==P[j]){i++;j++;}else{j=next[j];}if(j!=-1&&P[j]=='\0'){index[k++]=i-j;j=0;}} return k;
    }
    int main(){char t[]="abceeeabcyyyabc";char p[]="abc";int index[10];int n=kmpCheck(t,p,index);for(int i=0;i<n;i++){cout<<index[i]<<'\t';}cout<<endl;return 0;
    } 

    本来想详细讲解一下KMP算法的原理,后来发现我自己的语言表达确实有点拙劣,倒是花了很长的时间画图,也简单说了一下如何手算一个kmp算法的回溯值矩阵。至于算法的实现就是草草的贴了几个代码。能力有限,还希望不当之处大家及时和我讲出来。

KMP算法——快速求失效函数值及其代码实现相关推荐

  1. 模式搜索的KMP算法详解与C语言代码实现

    Table of Contents 模式搜索的KMP算法 如何更好地理解和掌握 KMP 算法? 推荐文章 Knuth-Morris-Pratt 字符串查找算法,简称为 "KMP算法" ...

  2. (算法)通俗易懂的字符串匹配KMP算法及求next值算法

    大多数据结构课本中,串涉及的内容即串的模式匹配,需要掌握的是朴素算法.KMP算法及next值的求法.在考研备考中,参考严奶奶的教材,我也是在关于求next值的算法中卡了一下午时间,感觉挺有意思的,把一 ...

  3. 【C++】欧几里德算法快速求最大公约数

    问题描述:如何快速求解2个正整数的最大公约数. 欧几里德(Euclid)算法,也既常说的"辗转相除法",用于计算2个正整数的最大公约数(Greatest Common Diviso ...

  4. 算法 快速求一个整数的7倍

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 乘法运算 ...

  5. 算法 - 快速求一个整数的7倍

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 乘法运算相对比较慢,所以快速的方法就是将这个乘法转换 ...

  6. KMP算法(快速找出字串)

    核心:通过寻找公共前后缀找出next数组 前后缀: 前缀:以第一个字母开头,但不包含最后一个字母 后缀:以最后一个字母结尾,但不包含第一个字母 注:若当前字符的前一位的最长公共前后缀(len)为2,则 ...

  7. Kmp算法之 求最大公共前后缀

    先抛问题1:如果我们已知一个字符str的最大公共前后缀长度,当这个str再添加一个字符的str2,如何判断这个新的str2的最大公共前后缀长度?? 结论:只要将新添加的字符,与str的最大公共前后缀中 ...

  8. 新冠病毒检测系统(KMP算法)求解答

    要求 :

  9. KMP算法求next数组

    1.简介 Knuth-Morris-Pratt 算法,简称 \text{KMP}KMP 算法,由 \text{Donald Knuth}Donald Knuth.\text{James H. Morr ...

最新文章

  1. QluOJ2018NewCode计算几何(寄蒜几盒)
  2. Spring boot的Restful风格CRUD
  3. windows下 sbulime text 安装less2css踩的几个坑
  4. hadoop的关键进程
  5. Spring MVC @RequestMapping Annotation示例
  6. 纪念逝去的岁月——C/C++快速排序
  7. 读书笔记 计算机系统--系统架构与操作系统的高度集成 第二章处理器体系结构...
  8. 中医针灸学综合练习题库【10】
  9. z世代中的z是什么意思_开放是与Z世代合作的关键
  10. Excel妙用-公式结果我都要
  11. 多服务器显卡使用状态监控工具实现
  12. Gamma Correction/Gamma校正/灰度校正/亮度校正(已更正) - 部分 DCC 中的线性工作流配置
  13. web前端项目(一) 做一个网易考拉官网 常规静态页面 + 页面放到http服务 + 前后端分离
  14. Tik Tok小店:英国tiktok小店怎么核对结算
  15. Semantic Object Segmentation in Weakly Labelled Videos via A Self-Paced Fine-Tuning Network
  16. MAC 安装 pyenv
  17. java数组循环_java数组,遍历数组
  18. Apache Beam简介及相关概念
  19. 新手怎么开网店(网上开店注意事项及流程详解)
  20. Python扫雷游戏源代码及图片素材

热门文章

  1. 快速排序法(随缘学习)
  2. JAVA获取全国邮编和长途区号
  3. 解决socket连接超时问题
  4. 至少8位密码,包括大写、小写、数字、特殊字符中的三种即可!
  5. Swiftui:自定义Tabbar
  6. Java爬虫(二)-- httpClient模拟Http请求+jsoup页面解析
  7. SOLIDWORKS钣金设计基础命令
  8. 电商数据仓库的架构、模型与应用实践
  9. “微店一键搬家”与“微店一键复制”是同一个意思吗
  10. 优雅编程之这样注重实效,你就“正常”了(十二)