kmp算法中的nextval实例解释
求nextval数组值有两种方法,一种是不依赖next数组值直接用观察法求得,一种方法是根据next数组值进行推理,两种方法均可使用,视更喜欢哪种方法而定。 本文主要分析nextval数组值的第二种方法
a b a a b c a c 模式值
0 1 1 2 2 3 1 2 next数组
0 1 0 2 1 3 0 2 nextval数组 1.第一位的nextval值必定为0,第二位如果于第一位相同则取相同值下的next值为0,如果不同则取当下next的值为1。
2.第三位的next值为1,那么将第三位和第一位进行比较,均为a,相同,则,第三位的nextval值为0。
3.第四位的next值为2,那么将第四位和第二位进行比较,不同,则第四位的nextval值为其next值,为2。
4.第五位的next值为2,那么将第五位和第二位进行比较,相同,第二位的next值为1,则继续将第二位与第一位进行比较,不同,则第五位的nextval值为第二位的next值,为1。
5.第六位的next值为3,那么将第六位和第三位进行比较,不同,则第六位的nextval值为其next值,为3。
6.第七位的next值为1,那么将第七位和第一位进行比较,相同,则第七位的nextval值为0。
7.第八位的next值为2,那么将第八位和第二位进行比较,不同,则第八位的nextval值为其next值,为2。
三、next和nextval比较
Next数组的缺陷举例如下:
比如主串是“aab…..” 省略号代表后面还有字符。
模式串“aac”
通过计算aac的next数组为012(另外,任何字符串的第二位字符的next总是1,因此你可以认为他固定为1)
当模式串在字符c上失配时,会跳到第2个字符,然后再和主串当前失配的字符重新比较,即此处用模式串的第二个a和主串的b比较
即 aab aac
显然a也不等于b。然后 会跳到1,接着比,然后又失配,直到最后才使主串后移一位。
而“aac”的nextval数组为002 当在c失配时会跳到2,若还失配就直接跳到0,比next数组少比较了1次。
在如果模式串很长的话,那可以省去很多比较,因此你应该使用nextval数组。
四、严蔚敏
上:http://v.youku.com/v_show/id_XODYxNjExODQ=.html 第 34分钟开始
下:http://www.56.com/u28/v_NjAwMzA0ODA.html
五、代码实现:
public static void main(String [] args) throws IOException{//main函数,输入主串和模式串
System.out.print("请输入主串:");
Scanner sn1 = new Scanner(System.in);
String s1 = sn1.next();
System.out.print("请输入模式串:");
Scanner sn2 = new Scanner(System.in);
String s2 = sn2.next();
char [] s3 = s1.toCharArray();
char [] s4 = s2.toCharArray();
System.out.print(KMP_test(s3,s4));
}
public static int KMP_test(char [] s, char [] t){// 主串顺序匹配
int [] next = next(t);
int i = 0, j = 0;
while(i
if(j == -1 || s[i] == t[j]){
++i;
++j;
}else{
j = next[j];
}
}
System.out.println(i);
if(j
return 0;
}else{
return i-t.length;
}
}
public static int [] next(char [] t){// next函数求解
int i = 0, j = -1;
int [] next = new int[t.length];
next[0] = -1;
while(i
if(j == -1 || t[i] == t[j]){
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
System.out.println(Arrays.toString(next));
return next;
}
对于改进的KMP算法,只需要把next函数换为nextval函数就行了
public static int [] next(char [] t){
int i = 0, j = -1;
int [] next = new int[t.length];
next[0] = -1;
while(i
if(j == -1 || t[i] == t[j]){
++i;
++j;
if (t[i] != t[j]) {
next[i] = j;
} else {
next[i] = next[j];
}
}
else
j = next[j];
}
System.out.println(Arrays.toString(next));
return next;
}
kmp算法中的nextval实例解释的更多相关文章
- 问题 1690: 算法4-7:KMP算法中的模式串移动数组
题目链接:https://www.dotcpp.com/oj/problem1690.html 题目描述 字符串的子串定位称为模式匹配,模式匹配可以有多种方法.简单的算法可以使用两重嵌套循环,时间复杂 ...
- KMP算法中我对获取next数组的理解
之前在学KMP算法时一直理解不了获取next数组的函数是如何实现的,现在大概知道怎么一回事了,记录一下我对获取next数组的理解. KMP算法实现的原理就不再赘述了,先上KMP代码: 1 void g ...
- KMP 算法中的 next 数组
KMP 算法中对 next 数组的理解 next 数组的意义 此处 next[j] = k:则有 k 前面的浅蓝色区域和 j 前面的浅蓝色区域相同: next[j] 表示当位置 j 的字符串与主串不匹 ...
- KMP算法中next函数的理解
首先要感谢http://blog.csdn.net/v_july_v/article/details/7041827以及http://blog.chinaunix.net/uid-27164517-i ...
- KMP算法的next[]数组通俗解释
原文:https://blog.csdn.net/yearn520/article/details/6729426 我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见的改进算法,它可以 ...
- KMP算法中next数组的理解与算法的实现(java语言)
KMP 算法我们有写好的函数帮我们计算 Next 数组的值和 Nextval 数组的值,但是如果是考试,那就只能自己来手算这两个数组了,这里分享一下我的计算方法吧. 计算前缀 Next[i] 的值: ...
- KMP算法中求next数组的实质
在串匹配模式中,KMP算法较蛮力法是高效的算法,我觉得其中最重要的一点就是求next数组: 看了很多资料才弄明白求next数组是怎么求的,我发现我的忘性真的比记性大很多,每次看到KMP算法求next数 ...
- KMP算法中next数组的构建
记得初学$kmp$的时候 老师让大家把它直接背下来 然而不理解的话 不仅调试起来比较慢 很多题目也难往$kmp$上想 ----------------------------------------- ...
- 关于KMP算法中,获取next数组算法的理解
参考:KMP入门级别算法详解--终于解决了(next数组详解) https://blog.csdn.net/lee18254290736/article/details/77278769 在这里讨论的 ...
随机推荐
- Node.js中package.json中^和~的区别
webpack 项目的package.json 文件列出了项目所依赖的插件和库,同时也给出了对应的版本说明,但是在版本说明前面还有个符号:'^'(插入符号)和'~'(波浪符号),总结了下他们之间的区别 ...
- python group()--转载
import re a = "123abc456" print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0) ...
- 小米笔记本 air 12.5寸 支持硬盘参数
M.2接口 2280规格 单面芯片固态硬盘 PCIE协议
- kali删除软件
kali中主要为2种卸载方法:1.apt2.dpkg 使用apt的方式有:apt-get remove [package]apt-get remove --purge # ------(package ...
- STL_算法_中使用的函数对象
写在前面: STL算法中的 函数对象的功能: (1).都是提供一种比较的函数,比较相邻的左右两个值的 相等/大小 等的关系, (2).返回值都是bool :该返回值 貌似是指明 遍历元素是否还要继续往 ...
- MySQL函数GROUP_CONCAT() 实现多条数据合并
group_concat()会计算哪些行属于同一组,将属于同一组的列显示出来,group by指定的列进行分组. 例如: -- 根据物流订单id查询所有物流订单,车源订单,车辆信息(多条数据合并为一条 ...
- angular5 生命周期钩子函数
生命周期执行顺序ngOnChanges 在有输入属性的情况下才会调用,该方法接受当前和上一属性值的SimpleChanges对象.如果有输入属性,会在ngOnInit之前调用. ngOnInit 在组 ...
- OpenGL入门程序二:绘制简单的圆
学习 绘制一个圆: ; const float Pi = 3.1415926536f; const float R = 0.5f; //绘制一个圆 void DrawCircle() { //绘制一个 ...
- import 与 import static
原文链接:https://www.geeksforgeeks.org/static-import-java/ java中的静态引用 直接解释 一般引入类的方式:import java.lang.Mat ...
- C#退出模式
1.this.Close(); 只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外若有托管线程(非主线程),也无法干净地退出: 2.Application.Exit(); 强制所有消息中 ...