提示:可搭配B站比特大博哥视频学习:传送门 (点击)

目录

前言

图解

代码


前言

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特一莫里斯―普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。来自

-------百度百科。

区别: KMP和BF唯一不一样的地方在,我主串的i并不会回退,并且j也不会移动到0号位置

图解

1.为什么主串下标j不用回退到0:

现在是在子串2号位置匹配失败,j回退到0,i回退到1,此时两个字符串还是不匹配

2.j回退的位置:主串下标用i表示,字串下表用j表示

引出next数组

KMP的精髓就是next数组:也就是用next[j]= k;来表示,不同的j来对应一个k值,这个k就是你将来要移动的j要移动的位置。
而k的值是这样求的:
1、规则:找到匹配成功部分的两个相等的真子串(不包含本身),一个以下标0开始,另一个以j-1下标结尾。
2、不管什么数据next[0] = -1;next[1] =0;在这里,我们以下标来开始,而说到的第几个第几个是从1开始;
练习:

举例:

第二个数组,第一个元素a默认是-1,

第二个元素b默认是0,

第三个元素c判断a到c前面一个元素b之间区间,有没有从a开始以a结束的两个相等的真子串,没有,因为a之后就是b了,

第四个元素a,然后看他前面abc中,没有两个相等的真子串,

第五个元素b,前面abca中,从前看有a,从后看有a,所以有两个相等的真子串,长度为1,

第六个元素c,前面abcab中,从前看有ab,从后看有ab,所以有两个相等的真子串,长度为2,

第七个a,前面abcabc中,前面有abc后面有abc,所以长度是3

第八个元素b,前面abcabca中,前面有abca,后面有abca,所以长度是4

第九个元素c,前面abcabcab中,前面有abcab,后面有abcab,所以长度是5

第14个元素a,前面abcabcabcabcd,前面和后面没有对应的元素,所以长度是0

第二个数组的数字8怎么来的:

首先第一个真子串的起始位置必须从0开始,abcabcab,第二个真子串的终止位置必须是j-1号下标即b(对应值是7(非下标)),abcabcab(从对应值0开始(下标是3))

总结出来的思路是,第一个位置直接给-1,默认的,第二个给0,因为前一个位置只有一个值,找到最长的前缀(第一个字符串)和后缀(第二个字符串)

代码

前面都和BF算法差不多,只是当出现字符不匹配的时候,j要回退到在next数组中,j对应的值。

而构建next数组时,默认第一个值给-1,第二个值给0(前面只有一个值)

当前一项的值和当前i-1下标的值相等时,同时往后记录,并且将i的位置值设置k+1

当前一项的值和当前i-1下标的值不相等时,则将k退回到上一个位置

void getnext(const char* sub, int* next, int Sublen) {next[0] = -1;if (Sublen == 1)return;next[1] = 0;int i = 2;//当前i的下标int k = 0;//前一项的kwhile(i< Sublen) {//当第一个值就不匹配的时候,++k会回到第一个值if (k == -1||sub[i - 1] == sub[k]) {next[i] = k+1;++i;++k;}else{k = next[k];}}
}//const常规操作了,防止数据被篡改
//pos代表从主串位置开始找
const int KMP(const char* str, const char* sub, int pos)
{//断言及时制止崩溃的程序assert(str != NULL && sub != NULL);//如果输入为空则返回-1if (str == NULL || sub == NULL){return -1;}//计算两个字符串的长度int Strlen = strlen(str);int Sublen = strlen(sub);if (pos < 0 || pos >= Strlen) {return -1;}int* next = (int*)malloc(sizeof(int) * Sublen);assert(next);getnext(sub, next, Sublen);//定义i为主串的指针,j为字串的指针,下标从0开始int i = pos;//从主串指定位置开始找int j = 0;//当i和j都没有超出字符串的长度时while (i < Strlen && j < Sublen){//开始匹配//当出现j第一个位置就不匹配时,j回到-1下标,此时++i,++j//i往后走,j回到第一个位置if (j == -1 || str[i] == sub[j]){i++;j++;}//匹配不成功则讲j回退else{j = next[j];}}free(next);//匹配到合适的字符串时if (j >= Sublen){//直接返回合适字符串的下标return i - j;}//没有找到合适字符串时返回-1return -1;
}

测试代码

int main()
{printf("%d\n", KMP("ababcabcabcde", "abcd", 0));//对应输出8printf("%d\n", KMP("ababcabcabcde", "abcdf", 0));//对应输出-1printf("%d\n", KMP("ababcabcabcde", "ab", 0));   //对应输出0return 0;
}

KMP算法(求解字符串匹配)相关推荐

  1. KMP算法,字符串匹配,next与nextval数组求解

    目录 KMP算法简介 next数组手动求解过程 next数组求解(代码实现) 改进的KMP算法 手动求解nextval数组 nextval数组求解(代码实现) KMP算法简介 KMP算法是一种改进的字 ...

  2. KMP算法(字符串匹配问题)acm寒假集训日记22/1/19

    首先,先看一道例题: 如果不考虑超时的话,我们完全可以用最朴素的方法(暴力)去求 //暴力算法(n*m) int ViolentMatch(char *s,char *p) {int sLen = s ...

  3. KMP算法(字符串匹配)

    对于KMP算法来言,我自己感觉文字介绍,方法理解起来相对于代码算是简单的, KMP算法介绍 1)KMP是一个解决模式串在文本串是否出现过,如果出现过,最早出现的位置的经典算法 2)Knuth-Morr ...

  4. 【数据结构与算法】字符串匹配 KMP 算法

    单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法 多模式串匹配算法 Trie 树和 AC 自动机 KMP 算法 KMP 算法是根据三位作者(D.E.Knuth,J.H.Morris ...

  5. 【数据结构与算法】字符串匹配 AC自动机

    单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法 多模式串匹配算法 Trie 树和 AC 自动机 AC 自动机 AC 自动机实际上就是在 Trie 树之上,加了类似 KMP 的 ne ...

  6. 【数据结构与算法】字符串匹配 BM算法

    单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法 多模式串匹配算法 Trie 树和 AC 自动机 BM算法 BM算法的核心思想是通过将模式串沿着主串大踏步的向后滑动,从而大大减少比较 ...

  7. 【数据结构与算法】字符串匹配 BF算法 RK算法

    单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法 多模式串匹配算法 Trie 树和 AC 自动机 一.BF 算法 1,BF算法是Brute Force的缩写,中文译作暴力匹配算法,也 ...

  8. 【C#】KPM算法解决字符串匹配问题

    KPM算法解决字符串匹配问题 什么是KPM算法 步骤 Ⅰ根据<最大长度表>部分匹配表(next) 寻找最长前缀后缀 Ⅱ 根据 部分匹配表 进行匹配 代码实现 什么是KPM算法   Knut ...

  9. java 蓝桥杯算法提高 字符串匹配(题解)

    试题 算法提高 字符串匹配 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行.你的程序还需支持大小写敏感选项:当选项打开时 ...

  10. 基于KMP算法的字符匹配问题

    基于KMP算法的字符匹配问题 反正整个清明都在纠结这玩意-差点我以为下个清明要给自己过了. 至于大体的理解,我就不再多说了(还要画图多麻烦鸭),我参考了以下两个博客,写的真的不错. (原创)详解KMP ...

最新文章

  1. Java中数组常见的几种排序方法!
  2. CoRL 2020奖项公布,斯坦福获最佳论文奖,华为等摘得最佳系统论文奖
  3. IT职场中外企面试最爱提的问题TOP10
  4. springmvc 中@Controller和@RestController的区别
  5. oracle us7ascii 中文,US7ASCII字符集中汉字显示问题
  6. 清明节特辑 |记忆存储、声音还原、性格模仿……AI可以让人类永生吗?
  7. 法拉第未来FF91付费预订仅300台,国内关联公司存在失信
  8. java 静态方法_自学JAVA每日记录(11)-欢迎指点欢迎共勉
  9. 【SQL】查询数据库中某个字段有重复值出现的信息
  10. 树莓派+docker+tensorflow
  11. lopatkin俄大神精简中文系统Windows 10 1607 Enterprise LTSB 2016 x86-x64 ZH-CN 2x1
  12. 计算机网路课程设计——电子邮件客户端的设计与实现——接收邮件(POP3协议)
  13. 计算机管理显示磁盘未知,磁盘未知,未初始化或未分配问题的解决方案
  14. php爬拉钩数据,拉勾网数据两种爬取
  15. 建立网站费用大概需要多少钱?
  16. 俞敏洪:35岁前如何实现自我增值?
  17. html页面回退,HTML5小结
  18. Leetcode-数据结构-118. 杨辉三角
  19. Excel空白单元格如何填充上方的数据
  20. [导入]教你如何和女孩接吻缠绵

热门文章

  1. nginx修改根目录
  2. 2018 软件测试人员的成长之路---必看!
  3. 清纯非主流_陕南赤子_新浪博客
  4. aapt 获取Android版本信息和图标
  5. 数据分析(数据指标+数据工具)
  6. 安卓手机微信记录还能找回吗
  7. 中国Q4净利3180万美元
  8. 大家来说说做网站有必要花费上万吗?
  9. 无参考图像的质量评价
  10. 被G20、APEC、瑞典、新加坡、俄罗斯等引用的GCI报告,今年有什么新发现?