你真的理解KMP算法么?

KMP算法是一个非常经典的字符串匹配的算法,它讲的是,我们给定两个字符串str1与str2,长度分别问N和M,实现一个算法,如果字符串str1,包含str2,则返回str2在str1中的开始位置,不包含则返回-1。
题意很容易理解,如下图:当str1与str2为abcdabce与abce的时候,二者匹配,返回abce在str1中开始位置的下标3,当str1与str2为abcdabce与abcf的时候,二者不存在包含关系,返回-1。
在这里插入图片描述
大多数人看到这个题目,第一个想到的方法肯定是暴力比对,将str2从str1的第一个字符位置开始比对,如果能够匹配上则返回,不能匹配就从第二个,第三个…直到匹配上或者匹配失败,不可否认,采用这种方法确实能够完成需求,但是所耗费的时间复杂度是O(M*N),那么有没有什么能够降低时间复杂度的办法呢,我们的KMP算法就闪亮登场了,在开始介绍之前,我们先了解一个概念,字符串str的nextArr数组,这个数组有什么特点:
1.这个数组的长度与str字符串的长度一样

2.nextArr[i]的含义就是str[i]之前的字符串str[0…i-1]中必须以str[i-1]结尾的后缀子串,(不能包含str[0])与必须以str[0]开头的前缀子串(不能包含str[i-1])的最大匹配长度。

下面举个简单的例子,大家就明白了,假设我们有一个字符串str为abcdabcd,那么它的nextArr数组是怎么得出来的呢,先把结果列出来,结果就是:[-1,0,0,0,0,1,2,3]。
下面就详细介绍一下这个结果是怎么出来的:

  1. 首先当i=0的时候,str[0]之前没有任何字符串了,默认此时值为-1

  2. 接下来i=2的时候,str[1]之前只有一个字符串a,此时默认为0

  3. 接下来i=2,str[2]之前的字符串为ab,此时a与b不等,nextArr[2]=0

  4. 接下来i=3,str[3]之前的字符串为abc,nextArr[3]=0

  5. 同理,nextArr[4]=0

  6. 一直到i=5的时候,str[5]之前是abcda,此时有一个字符a,是前缀子串与后缀子串的匹配字符,nextArr[5]=1

  7. 当i=6的时候,str[5]之前是abcdab,此时有一个字符串ab,是前缀子串与后缀子串的最长匹配,nextArr[6]=2

  8. 同理nextArr[7]=3

下面看当我们得到这个nextArr数组之后,它是如何优化时间复杂度的。

回到我们最初的问题上来,我们要解决的问题是判断字符串str1是否包含str2
在这里插入图片描述
如上图所示,a串与b串是字符串str2[0…j-1]的前缀子串与后缀子串相匹配的最长字符串,即a与b相等,假设str1与str2在叉号左边部分完全匹配上了,但是到str2[j]的位置匹配失败,即str2[j]不等于str1[i],此时,注意,我们的做法不再是将str2只向右滑动一个单位,而是向右滑动j-nextarr[j] (已匹配长度-前缀与后缀最大公共长度)个单位,然后再继续以上过程,开始匹配,这样就完成了时间复杂度的优化工作,这一步也是KMP算法的核心步骤。

现在假设我们有一个方法可以获取一个字符串的nextArr数组,假设这个方法名为getNextArr,下面附上KMP算法的代码:

		pubic int getIndex (String str1, String str2){
		//如果两个字符串都为空,或者匹配串的长度大于被匹配串的长度,直接返回-1
			if (str1 == null || str2 == null || str2.length > str1.length) {
				return -1;
			}
			char[] ch1 = str1.toCharArray();
			char[] ch2 = str2.toCharArray();
			//i,j分别表示在str1与str2的指针,当j走到str2的最后一个字符的时候,说明匹配成功。
			int i = 0;
			int j = 0;
			int[] nextArr = getNextArray(ch2);
			while (i < ch1.length && j < ch2.length) {
			//如果匹配上就进行下个位置的对比 
				if (ch1[i] == ch2[j]) {
					i++;
					j++;
				} 
				//如果nextArr[j]==-1,则说明匹配串index为0,只有此处默认值为-1;
				else if (nextArr[j] == -1) {
					i++;
				}
				//否则,匹配串向右滑动,这里的j = nextArr[j]可以理解为向右滑动			
			  else {
					j = nextArr[j];
				}
			}
			return j == ch2.length ? i - j : -1;

		}

接下来就介绍一下如何获取nextArr数组

前面就介绍过按照规定字符串第一个字符对应的数组值为-1,第二个为0,即nextArr[0] = -1;nextArr[1] = 0;
对于后面的求解过程,下面详细介绍:
因为是从左到右依次求解,所以当求解nextArr[i]的时候,nextArr[i-1]已经求解出来,通过它的值可以知道B字符前字符串的最长前缀与最长后缀的匹配区域,a区域与b区域,字符C与字符B分别是紧贴着这两个区域后面的字符,由此可知,如果C字符与B字符相同,那么nextArr[i]=nextArr[i-1]+1。

在这里插入图片描述
如果字符C与字符B不等,那么就看字符C之前的前缀与后缀的匹配情况了,假设字符C是第cn个字符,那么nextArr[cn]就是其最长前缀与后缀匹配的长度,如下图所示,那么,n与m两个就是最长前缀与后缀区域,m’是b区域的最右区域且长度与m区域长度一致,那么m与m’一定是相等的,字符D是n区域后面一个元素,如果D字符与B字符相等,那么nextArr[i]=nextArr[cn]+1。如果不等那么继续往前跳到字符D,之后的过程与跳到C一致,每跳一次都会出现一个字符与B比较,如果相等,nextArr[i]就可以确定。如果跳到最左的位置,此时nextArr[0]=-1,此时说明字符A之前的字符串不存在前缀后缀匹配,令nextArr[i]=0;
在这里插入图片描述
具体代码如下:

		public int[] getNextArray (String s){
			char[] ch = s.toCharArray();
			if (ch.length == 1) {
				return new int[]{-1};
			}
			int[] nextArr = new int[ch.length];
			nextArr[0] = -1;
			nextArr[1] = 0;
			int pos = 2;
			int cn = 0;
			while (pos < next.length) {
			//如果字符B等于字符C,加一
				if (ch[pos - 1] == ch[cn]) {
					next[pos++] = ++cn;
				} else if (cn > 0) {
					cn = next[cn];
				} else {
					next[pos++] = 0;
				}
			}

			return next;

		}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数字乡村和智慧农业的数字化转型是当前农业发展的新趋势,旨在通过应用数字技术,实现农业全流程的再造和全生命周期的管理服务。中国政府高度重视这一领域的发展,提出“数字中国”和“乡村振兴”战略,以提升国家治理能力,推动城乡融合发展。 数字乡村的建设面临乡村治理、基础设施、产业链条和公共服务等方面的问题,需要分阶段实施《数字乡村发展战略纲要》来解决。农业数字化转型的需求包括满足市民对优质农产品的需求、解决产销对接问题、形成优质优价机制、提高农业劳动力素质、打破信息孤岛、提高农业政策服务的精准度和有效性,以及解决农业融资难的问题。 数字乡村建设的关键在于构建“1+3+4+1”工程,即以新技术、新要素、新商业、新农民、新文化、新农村为核心,推进数据融合,强化农业大数据的汇集功能。数字农业大数据解决方案以农业数字底图和数据资源为基础,通过可视化监管,实现区域农业的全面数字化管理。 数字农业大数据架构基于大数据、区块链、GIS和物联网技术,构建农业大数据中心、农业物联网平台和农村综合服务指挥决策平台三大基础平台。农业大数据中心汇聚各类涉农信息资源和业务数据,支持大数据应用。信息采集系统覆盖市、县、乡、村多级,形成高效的农业大数据信息采集体系。 农业物联网平台包括环境监测系统、视频监控系统、预警预报系统和智能控制系统,通过收集和监测数据,实现对农业环境和生产过程的智能化管理。综合服务指挥决策平台利用数据分析和GIS技术,为农业决策提供支持。 数字乡村建设包括三大服务平台:治理服务平台、民生服务平台和产业服务平台。治理服务平台通过大数据和AI技术,实现乡村治理的数字化;民生服务平台利用互联网技术,提供各类民生服务;产业服务平台融合政企关系,支持农业产业发展。 数字乡村的应用场景广泛,包括农业生产过程、农产品流通、农业管理和农村社会服务。农业生产管理系统利用AIoT技术,实现农业生产的标准化和智能化。农产品智慧流通管理系统和溯源管理系统提高流通效率和产品追溯能力。智慧农业管理通过互联网+农业,提升农业管理的科学性和效率。农村社会服务则通过数字化手段,提高农村地区的公共服务水平。 总体而言,数字乡村和智慧农业的建设,不仅能够提升农业生产效率和管理水平,还能够促进农村地区的社会经济发展,实现城乡融合发展,是推动中国农业现代化的重要途径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值