KMP算法中改进的nextval数组

改进的NEXT数组算法及其应用

我们在上篇文章中讲到的NEXT数组其实再某些情况下是有缺陷的,例如在模式串 s=’aaaab’ 和主串 t=’aaabaaaab’匹配时,当在i=4,j=4时,产生失配,由下图的next数组中指出还需进行 i=4,j=3;i=4,j=2;i=4,j=1这三次比较。但是我们发现这样的比较是没有意义的,因为s串中前四个字符都相等,所以不需要逐个与主串中的第4个字符进行比较。

这里写图片描述

所以此时我们应该考虑直接进行i=5,j=1的比较,这就是说,在我们求出next[j]=k时,而模式串中s[j]=s[k],则当匹配字符s[i]和t[j]比较不等时,不需要再进行s[k]和t[j]的比较,而是直接和s[next[k]]比较,换句话说就是如果存在s[j]=s[k]那么next[j]=next[k]。

在模式串中第一位固定有nextval[1]=0,第二位的next[2]应该为1,但是s[1]=s[2],所以我们取nextval[2]=nextval[1]=0,以此类推。

下面给出求nextval的算法:

void get_nextval(SString T,int nextval[]){
 i=1; nextval[1]=0; j=0;
 while(i<T[0
KMP(Knuth-Morris-Pratt)算法是一种高效的字符串匹配算法,其中next数组nextval数组起着关键作用。 next数组记录的是模式串中每个位置之前的子串的最长公共前后缀长度。在字符串匹配过程中,当发生不匹配时,利用next数组可以避免从头开始重新匹配,而是将模式串向右移动一定的位数,该位数由next数组的值决定,从而提高匹配效率。例如,在比较主串和模式串时,若在某个位置出现不匹配,通过next数组找到模式串中合适的位置继续与主串当前位置比较,减少不必要的比较次数,加快匹配速度[^1]。 nextval数组是对next数组的优化。它在记录信息时考虑了模式串中字符的重复情况。当模式串中存在重复字符时,使用next数组可能会进行一些不必要的回溯,而nextval数组能进一步避免这些不必要的回溯。在计算nextval数组时,若依照next数组指向的字符与所求字符相同,就将所求字符的next值更新为本来该字符next数组指向的字符的next值;若不相同,则保持不变。这样在匹配过程中可以更高效地跳过一些不必要的比较,进一步提升匹配效率[^1][3]。 ```python def get_next(pattern): m = len(pattern) next_arr = [0] * m j = 0 for i in range(1, m): while j > 0 and pattern[i] != pattern[j]: j = next_arr[j - 1] if pattern[i] == pattern[j]: j += 1 next_arr[i] = j return next_arr def get_nextval(pattern): next_arr = get_next(pattern) m = len(pattern) nextval = [0] * m for i in range(1, m): if pattern[i] == pattern[next_arr[i]]: nextval[i] = nextval[next_arr[i]] else: nextval[i] = next_arr[i] return nextval pattern = "abcabc" next_arr = get_next(pattern) nextval_arr = get_nextval(pattern) print("next数组:", next_arr) print("nextval数组:", nextval_arr) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值