nextval数组求解过程

  • 为什么用nextval数组
  • nextval数组求解方式
    • 一、模式串的下标从0开始,nextval数组求解方式详解:
      • 代码实现
    • 二、模式串的下标从1开始,nextval数组求解方式详解:
      • 代码实现

为什么用nextval数组

next数组在某些情况下仍存在缺陷,例如 模式串"aaaab"与主串"aaabaaaab"进行匹配时:

主串下标为0时的next数组为:

下标 0 1 2 3 4 5 6 7 8
主串 S a a a b a a a a b
模式串 T a a a a b
next[ ] -1 0 1 2 3

主串下标为1时的next数组为:

下标 1 2 3 4 5 6 7 8 9
主串 S a a a b a a a a b
模式串 T a a a a b
next[ ] 0 1 2 3 4

无论哪种方式,当匹配到第四位,主串为b,模式串是a,两者不相同,则主串b需要依次跟第三位a,第二位a,第一位a依次作对比,实际上,前三位与第四位都相同,显然与前三位的比较没有意义,一定会匹配失败。

nextval数组是对next数组进行的该进,减少这种无意义的比对。

nextval数组求解方式

已知串T=“ababaaababaa”;
利用next数组求nextval数组

下面从代码的角度讲述一下求解nextval[]的思路:1、可以确定nextval的第一位与next数组第一位相同
2、从第二位开始,依次判断该位置的next值对应的元素与该位置元素是否相同,
3、若相同,该位置的nextval的值就是该位置next值对应元素的nextval的值
4、若不同,该位置的nextval的值就是该位置的next值

一、模式串的下标从0开始,nextval数组求解方式详解:

1、可以确定第一位的值:nextval[0] = next[0] = -1;

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1

2、看第二位,也就是T[1] = b,T[1]next所对应的元素是T[0] = a,b与a不同,则T[1]的nextval的值就是T[1]的next值,nextval[1] = next[1] = 0

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1 0

3、看第三位,也就是T[2] = a,T[2]next所对应的元素是T[0] = a,a与a相同,则T[2]的nextval的值就是T[2]next对应元素的nextval的值: nextval[next[2]] = nextval[0] = -1
即:nextval[2] = nextval[0] = -1

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1 0 -1

4、看第四位,也就是T[3] = b,T[3]next所对应的元素是T[1] = b,b与b相同,则T[3]的nextval的值就是T[3]next对应元素的nextval的值: nextval[next[3]] = nextval[1] = 0即:nextval[3] = nextval[1] = 0

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1 0 -1 0

5、看第五位,也就是T[4] = a,T[4]next所对应的元素是T[3] = a,a与a相同,则T[4]的nextval的值就是T[4]next对应元素的nextval的值 是 nextval[next[4]] = nextval[2] = -1
即:nextval[4] = nextval[2] = -1

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1 0 -1 0 -1

6、看第六位,也就是T[5] = a,T[5]next所对应的元素是T[3] = b,a与b不同,则T[5]的nextval的值就是T[5]next值,nextval[5] = next[5] = 3

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1 0 -1 0 -1 3

7、看第七位,也就是T[6] = a,T[6]next所对应的元素是T[1] = b,a与b不同,则T[6]的nextval的值就是T[6]next值,nextval[6] = next[6] = 1

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1 0 -1 0 -1 3 1

8、看第八位,也就是T[7] = b,T[7]next所对应的元素是T[1] = b,b与b相同,则T[7]的nextval的值就是T[7]next对应元素的nextval的值 是 nextval[next[7]] = nextval[1] = 0
即:nextval[7] = nextval[1] = 0

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1 0 -1 0 -1 3 1 0

9、看第九位,也就是T[8] = a,T[8]next所对应的元素是T[2] = a,a与a相同,则T[8]的nextval的值就是T[8]next对应元素的nextval的值 是 nextval[next[8]] = nextval[2] = -1
即:nextval[8] = nextval[2] = -1

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1 0 -1 0 -1 3 1 0 -1

10、看第十位,也就是T[9] = b,T[9]next所对应的元素是T[3] = b,b与b相同,则T[9]的nextval的值就是T[9]next对应元素的nextval的值 是 nextval[next[9]] = nextval[3] = 0
即:nextval[9] = nextval[3] = 0

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1 0 -1 0 -1 3 1 0 -1 0

11、看第十一位,也就是T[10] = a,T[10]next所对应的元素是T[5] = a,a与a相同,则T[10]的nextval的值就是T[10]next对应元素的nextval的值 是 nextval[next[10]] = nextval[4] = -1
即:nextval[10] = nextval[4] = -1

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1 0 -1 0 -1 3 1 0 -1 0 -1

12、看第十二位,也就是T[11] = a,T[11]next所对应的元素是T[5] = a,a与a相同,则T[11]的nextval的值就是T[11]next对应元素的nextval的值 是 nextval[next[11]] = nextval[5] = 3
即:nextval[11] = nextval[5] = 3

下标 0 1 2 3 4 5 6 7 8 9 10 11
模式串 T a b a b a a a b a b a a
next[ ] -1 0 0 1 2 3 1 1 2 3 4 5
nextval[ ] -1 0 -1 0 -1 3 1 0 -1 0 -1 3

代码实现

void getNextval(char T[],int TLength) {int nextval[TLength];nextval[0] = -1;printf("next[0] = %d \n", nextval[0]);int i = 0, j = -1; //i表示下标,初始化为0;j表示nextval数组的值,初始化为-1while (i < TLength-1) {if (j == -1 || T[i] == T[j]) {i++;j++;if(T[i] != T[j]) { //不同,该位置的nextval的值就是该位置的next值nextval[i] = j;printf("nextval[%d] = %d \n", i, nextval[i]);} else{ //相同,该位置的nextval的值就是该位置next值对应元素的nextval的值nextval[i] = nextval[j];printf("nextvl[%d] = %d \n", i, nextval[i]);}}else{j = nextval[j] ;}}
}int main(){char T[] = {'a','b','a','b','a','a','a','b','a','b','a','a'};int TLength = 12;getNextval(T,12);eturn 0;
}

测试结果:

nextval[0] = -1
nextval[1] = 0
nextvl[2] = -1
nextvl[3] = 0
nextvl[4] = -1
nextval[5] = 3
nextval[6] = 1
nextvl[7] = 0
nextvl[8] = -1
nextvl[9] = 0
nextvl[10] = -1
nextvl[11] = 3

二、模式串的下标从1开始,nextval数组求解方式详解:

1、可以确定第一位的值:nextval[1] = next[1] = 0;

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0

2、看第二位,也就是T[2] = b,T[2]next所对应的元素是T[1] = a,b与a不同,则T[2]的nextval的值就是T[2]的next值,nextval[2] = next[2] = 1

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0 1

3、看第三位,也就是T[3] = a,T[3]next所对应的元素是T[1] = a,a与a相同,则T[3]的nextval的值就是T[3]next对应元素的nextval的值: nextval[next[3]] = nextval[1] = 0
即:nextval[3] = nextval[1] = 0

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0 1 0

4、看第四位,也就是T[4] = b,T[4]next所对应的元素是T[2] = b,b与b相同,则T[4]的nextval的值就是T[4]next对应元素的nextval的值: nextval[next[4]] = nextval[2] = 1
即:nextval[4] = nextval[2] = 1

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0 1 0 1

5、看第五位,也就是T[5] = a,T[5]next所对应的元素是T[3] = a,a与a相同,则T[5]的nextval的值就是T[5]next对应元素的nextval的值 是 nextval[next[5]] = nextval[3] = 0
即:nextval[5] = nextval[3] = 0

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0 1 0 1 0

6、看第六位,也就是T[6] = a,T[6]next所对应的元素是T[4] = b,a与b不同,则T[6]的nextval的值就是T[6]next值,nextval[6] = next[6] = 4

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0 1 0 1 0 4

7、看第七位,也就是T[7] = a,T[7]next所对应的元素是T[2] = b,a与b不同,则T[7]的nextval的值就是T[7]next值,nextval[7] = next[7] = 2

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0 1 0 1 0 4 2

8、看第八位,也就是T[8] = b,T[8]next所对应的元素是T[2] = b,b与b相同,则T[8]的nextval的值就是T[8]next对应元素的nextval的值 是 nextval[next[8]] = nextval[2] = 1
即:nextval[8] = nextval[2] = 1

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0 1 0 1 0 4 2 1

9、看第九位,也就是T[9] = a,T[9]next所对应的元素是T[3] = a,a与a相同,则T[9]的nextval的值就是T[9]next对应元素的nextval的值 是 nextval[next[9]] = nextval[3] = 0
即:nextval[9] = nextval[3] = 0

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0 1 0 1 0 4 2 1 0

10、看第十位,也就是T[10] = b,T[10]next所对应的元素是T[4] = b,b与b相同,则T[10]的nextval的值就是T[10]next对应元素的nextval的值 是 nextval[next[10]] = nextval[4] = 1
即:nextval[10] = nextval[4] = 1

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0 1 0 1 0 4 2 1 0 1

11、看第十一位,也就是T[11] = a,T[11]next所对应的元素是T[5] = a,a与a相同,则T[11]的nextval的值就是T[11]next对应元素的nextval的值 是 nextval[next[11]] = nextval[5] = 0
即:nextval[11] = nextval[5] = 0

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0 1 0 1 0 4 2 1 0 1 0

12、看第十二位,也就是T[12] = a,T[12]next所对应的元素是T[6] = a,a与a相同,则T[12]的nextval的值就是T[12]next对应元素的nextval的值 是 nextval[next[12]] = nextval[6] = 4
即:nextval[12] = nextval[6] = 4

下标 1 2 3 4 5 6 7 8 9 10 11 12
模式串 T a b a b a a a b a b a a
next[ ] 0 1 1 2 3 4 2 2 3 4 5 6
nextval[ ] 0 1 0 1 0 4 2 1 0 1 0 4

代码实现

void getNextval(char T[],int TLength) {int nextval[TLength];nextval[1] = 0;printf("nextval[1] = %d \n", nextval[1]);int i = 1, j = 0; //i表示数组下标,初始化为1;j表示next数组的值,初始化为0while (i < TLength-1) {if (j == 0 || T[i] == T[j]) {i++;j++;if(T[i] != T[j]) { //不同,该位置的nextval的值就是该位置的next值nextval[i] = j;printf("nextval[%d] = %d \n", i, nextval[i]);} else{ //相同,该位置的nextval的值就是该位置next值对应元素的nextval的值nextval[i] = nextval[j];printf("nextval[%d] = %d \n", i, nextval[i]);}}else{j = nextval[j] ;}}
}int main(){char T[] = {'*','a','b','a','b','a','a','a','b','a','b','a','a'};int TLength = 13;getNextval(T,13);return 0;
}

测试结果:

nextval[1] = 0
nextval[2] = 1
nextval[3] = 0
nextval[4] = 1
nextval[5] = 0
nextval[6] = 4
nextval[7] = 2
nextval[8] = 1
nextval[9] = 0
nextval[10] = 1
nextval[11] = 0
nextval[12] = 4

注意:这两种方式的细微差别,整体思路一致,注意nextval起始位置以及边界条件,根据自己实际情况选择

nextval数组求解相关推荐

  1. KMP算法,字符串匹配,next与nextval数组求解

    目录 KMP算法简介 next数组手动求解过程 next数组求解(代码实现) 改进的KMP算法 手动求解nextval数组 nextval数组求解(代码实现) KMP算法简介 KMP算法是一种改进的字 ...

  2. 数据结构:详解KMP算法,手工求解next、nextval数组,求模式串的比较次数例题

    KMP 算法 手工求解 next 数组,nextval数组 例题:求模式串的比较次数 2019 年 408 统考真题 设主串 T="abaabaabcabaabc",模式串 S=& ...

  3. nextval数组如何求解

    nextval数组示例 j 1 2 3 4 5 6 7 8 9 模式串T a b a b a a a b a next 0 1 1 2 3 4 2 2 3 nextval 0 1 0 1 0 4 2 ...

  4. 字符串匹配KMP算法中Next[]数组和Nextval[]数组求法

    数据结构课本上给了这么一段算法求nextval9[]数组 1 int get_nextval(SString T,int &nextval[ ]) 2 { 3 //求模式串T的next函数修正 ...

  5. 【KMP】从原理上详解next数组和nextval数组

    本文将从原理上详细解释KMP算法中的next数组以及nextval数组,尽量让大家明白它们到底在记录什么,为什么要这样算.以及现在普遍的KMP算法实现当中的next数组与前两者有何不同.篇幅较长,但尽 ...

  6. 串的模式匹配、KMP算法、nextval数组求法

    一.暴力匹配 #include <iostream> using namespace std; #define MAXLEN 255 typedef struct{char ch[MAXL ...

  7. KMP算法总结+Next数组+Nextval数组

    KMP算法是一种用于比较字符串匹配的算法,适用于在一个串中找另一个串是否存在,在这里如果不用字符串中的函数的话,一般能想到的第一种方法就是暴力,即从第一位开始比较. ①暴力方法 查找串:1 2 1 2 ...

  8. 4. 串的【朴素模式匹配算法】、【KPM算法:求next数组、nextval数组】

    串的模式匹配:在主串中,找到与模式串相同的子串,并返回其所在位置. 其实就是给出一个串abc,找到abc在主串的位置[abc都要匹配] 模式串:给出一个串abc 子串:主串中的abc[可能没有] 文章 ...

  9. 用滚动数组求解0/1背包问题

    用滚动数组求解0/1背包问题(此处仅求装入背包的最大价值) // 由于第i个阶段(考虑物品i)的解dp[i][ * ]只与第i-1个阶段(考虑物品i-1)的解dp[i-1][ * ]有关,这种情况下保 ...

最新文章

  1. Python 三十大实践、建议和技巧(附代码链接)
  2. java 重构函数_包会,教你用Java函数式编程重构烂代码
  3. Web开发技巧:使用自定义数据属性创建弹出窗口
  4. 打开指定大小的新窗体
  5. delphi mysql
  6. 移动通信USSD业务探讨(转)
  7. 【IDEA】如何修改已创建的文件类型,虽然很无脑,但是也很棘手
  8. 物联网、大数据和云计算的基本关系和应用
  9. 自我管理--做事要有明确的时间观念
  10. 5000多字深度分析:从电视剧《鱿鱼游戏》看国内SaaS行业
  11. 禁止查看网络计算机方法,电脑如何禁止程序联网的方法
  12. Xshell6和Xftp6 破解免安装版,无窗口多开限制
  13. 2021-09-03 【N02】小程序开发学习笔记
  14. 对撞机 (Standard IO)
  15. 2018.8.18日,直播笔记
  16. pyspark--创建DataFrame
  17. 使用go实现反向代理
  18. ubuntu boost运行./bootstrap.sh后出现Failed to build B2 build engine
  19. 自建公有dns服务器,自建dns服务器的必要性
  20. 《c++简史》1.0

热门文章

  1. 使用腾讯云服务器快速搭建网站教程
  2. 高清壁纸大全:20款精美的2013年元旦桌面壁纸
  3. ubuntu svn客户端简单使用
  4. python+vue企业人力资源管理系统django569
  5. RGB565 to RGB24
  6. Apache 配置Http重定向到Https(两种方案任君选择)
  7. 大型WEB网站架构深入分析
  8. 数字系统实验:倒车雷达
  9. 异步机无传感控制MRAS-CC(一.调研学习)
  10. 大气污染扩散模型Calpuff教程