串的匹配算法——KMP算法

目录

一.特点

二.算法思想

三.公式证明

四.next数组及其练习

 五.找规律计算next[k]

六.代码实现


一.特点

BF算法的特点是i回退,KMP算法的最大特点是i不回退,由于i不回退,所以KMP算法的时间复杂度是O(n+m)。

二.算法思想

在匹配主串和子串时,i指向主串,j指向子串,字符相等则i,j同时加1,当字符失配时,i不回退,j退到k的位置(相当必然有一段相同的路,那么相同的路i不走,等着j走过来即可)即相等的路j走过一段k长度的路。

三.公式证明

结论:

 在匹配成功的子串中找到两个最长的相等的真子串,这两个子串满足如下特点:

  1. 一个串以子串的开头作为开头。
  2. 另一个串以失配前的最后一个字符作为结尾(p_{j-1})。
  3. k正是子串的长度。

四.next数组及其练习

我们把所有位置的k值给保存在数组中,这个数组就是next数组。

1.

2.

 3.

4.

 五.找规律计算next[k]

例子:“abcabcdabcdabcdeabc”

不妨假设next[j]=k;

已知:next[1]=0,next[0]=-1;

由next[j]=k,得到p_{0}...p_{k-1}=p_{j-k}...p_{j-1}  (1)

如果p_{k}=p_{j}   (2)

(1)+(2)=p_{0}...p_{k}=p_{j-k}...p_{j}

得到next[j+1]=k+1;

如图k=3

如果p_{k}!=p_{j}

又变成了一个模式匹配的问题,那么k=next[k];如图k=next[3]=0;

KMP最大特点是指示主串的指针不需要回溯,整个匹配过程中,对主串仅需从头到尾扫描一遍,这对处理从外设输入的庞大文件很有效,可以边读入边匹配,而无需回头重读。

六.代码实现

static int* GetNext(const char* str)
{int len = strlen(str);int* next = (int*)malloc(sizeof(int) * len);next[0] = -1;//不能再退next[1] = 0;//j=1,k=0;int j = 1;int k = 0;while (j+1 < len){if ((k==-1)||str[k] == str[j]){next[++j] = ++k;/*next[j + 1] = k + 1;j += 1;k += 1;*/}else{k = next[k];}}return next;
}int KMP(const char* str, const char* sub, int pos)
{assert(str != NULL && sub != NULL);if (str == NULL || sub == NULL || pos<0 || pos>strlen(str))return -1;int i = pos;int j = 0;int lenstr = strlen(str);int lensub = strlen(sub);int* next=GetNext(sub);//while (str[i] != '\0' && sub[j] != '\0')while (i < lenstr && j < lensub){if ((j==-1)||str[i] == sub[j]){i++;j++;}else{//i不回退j = next[j];}}free(next);//判断是否查找成功,利用子串是否遍历完成,来判断是否查找成功//if (sub[j] == '\0')if (j >= lensub)return i - j;elsereturn -1;
}int main()
{const char* str1 = "ababcabcdabcde";const char* str2 = "abcd";printf("%d\n", KMP(str1, str2, 0));printf("%d\n", KMP(str1, str2, 6));printf("%d\n", KMP(str1, str2, 10));return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/727359.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅谈社会工程学攻击

一、前言 1.1 社会工程学起源 社会工程学是黑客米特尼克在《欺骗的艺术》中所提出&#xff0c;其初始目的是让全球的网民们能够懂得网络安全&#xff0c;提高警惕&#xff0c;防止没必要的个人损失。但在我国黑客集体中还在不断使用其手段欺骗无知网民制造违法行为&#xff0c;…

String类,StringBuilder类,StringBuffer类

前言 String类&#xff0c;StringBuilder类&#xff0c;StringBuffer类都是java提供的定义字符串的类&#xff0c;下面是三种字符串类的异同介绍 String类&#xff1a;String类表示的字符串是是常量&#xff0c;一旦创建内容和长度都无法修改 StringBuilder类&#xff1a;St…

6个维度分析实时渲染和Webgl技术异同

在日常交流中&#xff0c;对Webgl技术熟悉的合作伙伴&#xff0c;在初次了解实时渲染技术时&#xff0c;都会问二者之间的异同。目前很多要求B/S架构的项目&#xff0c;很多在用webgl技术路线&#xff0c;而且这个方案在行业里比较普&#xff0c;业主方对这个也比较熟悉&#x…

JAVA实现图像取模

JAVA对图像取模 就是图片变成点阵 原图 取模效果图 代码如下&#xff1a; public static void main(String[] args) throws IOException {try {// 读取图像文件BufferedImage image ImageIO.read(new File("C:/Users/xiaol/Desktop/img/0.jpg"));// 定义阈值&am…

冬去春来天气阴晴不定 美食拿捏味蕾安稳换季

俗话说“春打六九头”&#xff0c;3月虽然已经入春&#xff0c;但是天气依然是凉飕飕的 &#xff0c;冬天春天的换季期&#xff0c;因为天气的变化&#xff0c;尤为痛苦。但是来到了换季期&#xff0c;天气也不总是那么稳定&#xff0c;随着气温的起伏&#xff0c;我们的食欲也…

Vue项目实战--空间论坛(1)

环境准备 安装好node.js,Vue后 添加插件 router---路由&#xff0c;多页面的应用 vuex---在多个组件之间维护同一个数据 添加依赖 bootstrap---美工 popperjs/core vue项目介绍 views-----对应vue文件&#xff0c;页面 router-----路由&#xff0c;页面&#xff0c;c…

《javascript高级程序设计》学习笔记 | 23.JSON

关注[前端小讴]&#xff0c;阅读更多原创技术文章 JSON JSON 是 JS 对象简谱&#xff0c;是一种通用的数据格式和 JS 有相同的语法&#xff0c;但不属于 JS&#xff0c;很多语言都能解析和序列化 JSON 相关代码 → 语法 JSON 支持 3 种类型的值 简单值&#xff1a;字符串、…

leetCode刷题 4.寻找两个正序数组的中位数

目录 1. 思路 2. 解题方法 3. 复杂度 4. Code 题目&#xff1a; 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 示例 1&#xff1a; 输入&…

1分钟带你搞定Python函数分类

python语言中&#xff0c;函数可以分为内置函数、自定义函数、有参数函数、无参数函数、有名字函数和匿名函数。其中&#xff0c;内置函数可以直接使用&#xff0c;自定义函数需要根据需求定义。有参数函数在定义时需要指定参数&#xff0c;调用时传入参数。无参数函数在定义时…

python基础 — 进制转换

1、进制引导符号 在 Python 中&#xff0c;可以使用不同的前缀&#xff08;引导符号&#xff09;来表示不同的进制。 以下是各种进制的引导符号&#xff1a; 二进制&#xff08;Binary&#xff09;&#xff1a;使用0b或0B作为前缀。例如&#xff1a;0b1010 表示二进制数 101…

SpringBoot 跨域配置

SpringBoot 跨域配置 添加配置文件 Configuration public class CorsConfig {private CorsConfiguration buildConfig() {CorsConfiguration corsConfiguration new CorsConfiguration();corsConfiguration.setAllowCredentials(true);// 设置访问源地址corsConfiguration.a…

git远程仓库使用

赋值这个地址clone 克隆之后 cd slam_oncloud/ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/slam_oncloud.git 查看一下 linuxchenxiao:/media/linux/mydisk/cloud_slam/slam_oncloud$ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/sla…

记录一次Dubbo远程调用的错误

情景&#xff1a;有一个生成PDF的接口中&#xff0c;如下&#xff1a; GET Path("/getPDF") public void getPDF(QueryParam("id") String id, Context HttpServletResponse response) {………… }之前实现的代码都写在了Controller里面&#xff0c;代码里…

【算法笔记】LeetCode_15_三数之和

LeetCode_15_三数之和 LeetCode 15 &#xff08;LeetCode 15) 题目描述 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复…

北斗卫星助力无人机在沙漠播种,促进沙漠治理

北斗卫星助力无人机在沙漠播种&#xff0c;促进沙漠治理 近年来&#xff0c;随着科技的不断发展&#xff0c;北斗卫星和无人机技术的结合被广泛应用于沙漠治理领域&#xff0c;为解决沙漠化问题提供了全新的思路和解决方案。 近日&#xff0c;黄河“几字弯”北岸的内蒙古自治…

《LeetCode力扣练习》代码随想录——二叉树(完全二叉树的节点个数---Java)

《LeetCode力扣练习》代码随想录——二叉树&#xff08;完全二叉树的节点个数—Java&#xff09; 刷题思路来源于 代码随想录 222. 完全二叉树的节点个数 二叉树-后序遍历 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeN…

[力扣100][好题] 121.买股票的最佳时机 || 动态规划

添加链接描述 思路&#xff1a; 设置一个动态数组dp用来存放当前最大的利润这个利润有两个来源&#xff1a;来源一是来自上一个最大利润&#xff1b;来源二是目前值减去最小买入价格如何维护最小值&#xff1f;预设一个最小值然后将这个最小值每次和当前值比较 class Solutio…

word打字后面的字消失是怎么回事

在使用Microsoft Word进行文档编辑时&#xff0c;很多用户可能会遇到一个令人困惑的问题&#xff1a;当在文档中打字时&#xff0c;后面的字却莫名其妙地消失了。这种情况不仅影响了编辑效率&#xff0c;还可能导致重要数据的丢失。那么&#xff0c;这一现象背后的原因是什么&a…

JVM3_数据库连接池虚引用ConnectionFinalizerPhantomReference引起的FullGC问题排查

背景 XOP服务运行期间&#xff0c;查看Grafana面板&#xff0c;发现堆内存周期性堆积&#xff0c;Full GC时间略长&#xff0c;需要调查下原因 目录 垃圾收集器概述 常见的垃圾收集器分区收集策略为什么CMS没成为默认收集器 查看JVM运行时环境分析快照 PhantomReference虚引用…

46. 全排列(力扣LeetCode)

文章目录 46. 全排列题目描述回溯算法 46. 全排列 题目描述 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],…