关于KMP算法中前缀函数(next函数)的一点个人理解

本文介绍了在KMP算法中前缀函数(next函数)的重要性,详细阐述了如何通过next数组处理字符串匹配时的失配情况。通过分析字符串的前后缀匹配,解释了next数组的生成规则,并提供了计算next数组的两种情况:当字符相等时,next值加1;当字符不等时,回溯到next[k]。通过实例演示加深了对前缀函数的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近再刷笔试题的时候,发现了几道题需要求取字符串的next数组。


关于这部分知识,之前是有学过,代码也是比较简洁的,如下:

	public static int[] getNext(String ps) {
		char[] p = ps.toCharArray();
		int[] next = new int[p.length];
		next[0] = -1;
		int j = 0;
		int k = -1;
		while (j < p.length - 1) {
			if (k == -1 || p[j] == p[k]) {
				next[++j] = ++k;
			} else {
				k = next[k];
			}
		}
		return next;
	}

但是对于KMP的描述,《算法导论》等教材中是有些隐晦复杂的,各个博客上的讲解也不尽相同。针对next数组这一块,综合了几家之长,我也简单描述下自己的想法,可以与大家相互探讨。


因为在kmp算法中,文本中的指针i是无法回溯的,所以最关键的是,next[j]的值(也就是k)表示,当P[j] != T[i]时,j指针的下一步移动位置。其中P为匹配字符串,T为原文。也就是说next数组其实就是查找P中每一位前面的子串的前后缀有多少位匹配,从而决定j失配时应该回退到哪个位置。

作为笔试题来说,思想比较简单。就是考虑从P[0 ~ k-1] == p[j-k ~ j-1]中k的个数,基本就可以数出来了。借用他人的说法就是(字符串匹配是 从头开始的 和 从尾开始的字符串进行匹配是否重复 


而在计算next数组时主要是以下两个步骤:

1. 当P[k] == P[j]时,有next[j+1] == next[j] + 1。

2. 当P[k] != P[j]时,有k = next[k]。

结合1和2可知,next[j]==k;

也就是说,P[0 ~ k-1] == p[j-k ~ j-1]中k的位置决定了next[j]的值。

以下列字符串为例:


跑了一下,结果如下:


相信对每一行逐行分析后,会对求取前缀函数有更深的了解



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值