【C语言】KMP算法(详解)
创始人
2025-05-28 04:22:38
0

目录

  • 1. 朴素的模式匹配
  • 2. KMP算法解决的问题
  • 3. KMP算法
    • 公共前后缀(重点)
    • next 数组
    • KMP算法实现

1. 朴素的模式匹配

  • 朴素算法中,当匹配到不同位时,主串指针i会退回到该次匹配起点处的下一位置,以其为下一次匹配的主串起点

  • 同时字串的j指针退回其起始位置

  • 如此一来每次匹配主串指针后移一位,字串指针始终在其起始位置

  • 时间复杂度为O(m*n)

在这里插入图片描述

2. KMP算法解决的问题

  • 可以发现下图中,在第二次匹配时,第一个元素就已经不一样了

  • 朴素算法的缺点就在于其会傻傻的执行许多次这样不必要的判断

  • 这就是KMP算法所解决的问题

在这里插入图片描述

3. KMP算法

  • 主串指针不会进行回溯,不会回到朴素匹配中的下一匹配点
  • 利用已匹配部分中的公共前后缀来调整字串指针位置,以此加速下一次匹配

根据下面的动画感受感受
在这里插入图片描述

  • 可以看到,主串指针( i )在整个查找过程中都没有前移,每次查找的起点均为上次查找的结束点,即 i 永远不递减,这也使KMP的精髓
  • 同时,当不匹配位置前一位对应的next数组中元素不为0时,字串指针( j )会向后偏移相应个数的字符
  • 这样一来,无论是主串还是字串的判断次数都得到了优化,时间复杂度优化至O(m+n)

公共前后缀(重点)

公共前后缀的计算:
这里用公式理解,计算下标为a处的公共前后缀个数,如果[a-x,a]范围的每一个元素与[0,x]范围的每一个元素相等,则a处的公共前后缀个数为x+1

在这里插入图片描述
 

这里注意找某一位置的公共前后缀时,要将起始位置的字符同该位置字符比较,而不是只要在该位置之前出现了相同元素就判断存在公共前后缀
如下图中的红色位置B,虽然在其之前存在一个字符B,但是该位置的公共前后缀为0

在这里插入图片描述

 
 
 

next 数组

理解了什么是公共前后缀,其实next数组就是存储该数组每个对应位置公共前后缀数量的数组
代码实现next数组

int* get_next(const char* p)
{assert(p);int len = strlen(p);int* next = (int*)malloc(sizeof(int) * len);if (next == NULL){return NULL;}else{//先将其全部初始化为0memset(next, 0, sizeof(int) * len);int j = 0;int i = 0;for (i = 1; i < 6; i++){if (p[i] == p[j]){next[i] = next[i - 1] + 1;j++;}else{j = 0;}}return next;}
}

 
 

KMP算法实现

注意代码注释

int my_kmp(char* a1, char* a2)
{int* next = get_next(a2);int len1 = strlen(a1);int len2 = strlen(a2);int i = 0;int j = 0;while (i < len1){if (a1[i] == a2[j]){i++;j++;}else if (j > 0)  // j>0 时,根据next数组调整 j 的位置j = next[j - 1];else   //字串第一个字符就不匹配i++;if (j == len2) //匹配成功,返回值为字串第一个字符在主串中的位置return i - j;}return -1;
}

相关内容

热门资讯

以色列冰激凌!北京「爆款」口感... 在北京繁华的商业区,一家不起眼的冰激凌店门前排起了长队,市民们顶着烈日,耐心等待两小时,只为品尝一口...
软件测试必备技能有哪些?   协同开发能力: 1. 项目管理(SVN、Git) 2....
docker 部署后端egg.... 我把egg.js文件夹上传到阿里云 在本地npm run dev 是正确的运行的,地...
北京 1700余场活动邀市民游... 5月26日,北京市人民政府新闻办公室举行2025年北京市“端午”假期文化和旅游系列活动新闻发布会。北...
有哪些好看颜值高的蓝牙耳机?高... 我们在选购的时候不仅仅看看参数,还要看颜值,小巧轻便,时尚...
高阶数据结构之图论 文章目录图是什么?图的存储邻接矩阵邻接表无向图邻接表存储有向图邻接表存储图的遍历广度优...
【多线程】 多线程多线程1.守护线程2.线程的生命周期3.线程同步机制4.互斥锁5.线程死锁6.释放锁 多线程 ...
用MyEclipse创建第一个... MyEclipse v2022.1.0正式版下载1. 企业应用项目模型MyEclipse提供了一个企...
Vue3——自定义封装上传图片... 自定义封装上传图片样式 一、首先需要新建一个自组建完善基础的结构,我这里起名为ImgU...
黄山旅游五天旅游费用多少,黄山... 黄山旅游五天旅游费用多少,黄山5日跟团游最佳路线 黄山,这座屹立于中国安徽省南部的神奇山脉,自古以来...
黄山五天参加旅游团攻略,黄山5... 黄山五天参加旅游团攻略,黄山5日游纯玩多少钱,黄山酒店 黄山,这座屹立于中国安徽省南部的神奇山脉,自...
“3.15”十五个行业大调查:... 疫情之后消费复苏,“烟火人间“回归日常。但是,部分行业的繁华羽翼之下却暗...
我该从哪些方向了解云原生领域? 你好,我是王炜。今天我们一起来看一看该从什么角度了解云原生领域。 说起云原生领域&#x...
这碗擀面皮,滋味十足(神州看点... 陕西日报记者 刘 坤 李静茹 在陕西,一碗源自宝鸡的擀面皮,不仅是餐桌上的家常味,更融入了关中地区...
端午节做这一桌就够了,有菜有肉... 端午节马上就要到了,除了吃粽子跟赛龙舟、挂艾草菖蒲以外,家宴也是缺一不可的。现在还有在烦恼不知道煮什...
【分享】用友U8无需API开发... 用友U8用户使用场景: 每当用友U8有存货修改时,需要仓库管理员查询存...
Python|randint|... 目录 1、随机生成一个具有 20 个元素的元素值在 1-10 之间的列表(散列表&#...
湖北武汉杨泗港长江大桥,围起来... 湖北武汉乃英雄之城,美食之城,旅游之城,历史文化厚重,美景众多,网红打卡点也很多,前不久因为武汉下了...
计算机科学导论笔记(十一) 目录 十三、文件结构 13.1 引言 13.1.1 顺序存取 13.1.2 随机存取 13.2 顺...