博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于KMP算法的重大发现
阅读量:4338 次
发布时间:2019-06-07

本文共 1278 字,大约阅读时间需要 4 分钟。

之前写KMP模板的时候,nx[i]代表最大的一个x,使s[1,x-1]是s[1,i-1]的后缀。(方法1)

然而网上还有另一种方法求nx数组,nx[i]表示最大的一个x,使s[1,x]是s[1,i]的后缀。(方法2)

两种nx数组在具体匹配的时候方法稍有不同,但都能正确匹配字符串。

但是在做字符串DP题的时候,发现网上的题解大多是利用第二种nx数组的性质进行状态的转移。

当时试着写了一下那种nx的求法,但是觉得很别扭,用不惯也记不住。

不知所措。

今天看了一下洛谷的KMP模板(P3375)(),发现得求出第二种nx数组......

这回把第二种求法忘了,也很反感那么写。

于是立志要找出两种方法的联系。

很简单嘛:nx2[i]=nx1[i+1]-1

同时,getnx的时候要走到m+1(m为模式串长),这样nx[m+1]才有值。

给一个洛谷P3375的代码。

注意getnx的改动和最后要求输出nx数组的时候是怎么操作的。

1 #include
2 #include
3 4 char s1[1000005],s2[1000005]; 5 int nx[1000005]; 6 int pos[1000005],cnt; 7 int n,m; 8 9 void getnx()10 {11 nx[1]=0;12 for(int i=2,j=1;i<=m+1;)13 {14 nx[i]=j;15 while(j&&s2[i]!=s2[j])j=nx[j];16 i++,j++;17 }18 }19 20 void kmp()21 {22 for(int i=1,j=1;i<=n;)23 {24 while(j&&s1[i]!=s2[j])j=nx[j];25 if(j==m)26 {27 pos[++cnt]=i-m+1;28 j=nx[j];29 }30 else i++,j++;31 }32 }33 34 int main()35 {36 scanf("%s",s1+1);37 scanf("%s",s2+1);38 n=strlen(s1+1);39 m=strlen(s2+1);40 getnx();41 kmp();42 for(int i=1;i<=cnt;i++)printf("%d\n",pos[i]);43 for(int i=1;i<=m;i++)printf("%d ",nx[i+1]-1);44 return 0;45 }

 

转载于:https://www.cnblogs.com/eternhope/p/9651420.html

你可能感兴趣的文章
知道这20个正则表达式,能让你少写1,000行代码
查看>>
MariaDB 主从同步与热备(14)
查看>>
推荐的 CSS 书写顺序
查看>>
NIO:与 Buffer 一起使用 Channel
查看>>
Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析
查看>>
Android - 广播机制和Service
查看>>
MFC接收ShellExecute多个参数
查看>>
volatile和synchronized的区别
查看>>
RocketMQ介绍与云服务器安装
查看>>
Jenkins插件HTML Publisher Plugin的使用
查看>>
A. The number of positions
查看>>
Windows中cmd的DOS命令查看占用某端口的程序及PID号
查看>>
设计多列布局
查看>>
返回一个整数数组中最大子数组的和
查看>>
解决FLASH遮住层的问题 IE,Firefox都适用!
查看>>
第七章:线程以及线程间的通信
查看>>
算法 PK 猫咪 | 章鱼保罗后继竟然是只猫?
查看>>
读书报告汇总
查看>>
rsync+inotify
查看>>
linux 创建连接命令 ln -s 软链接
查看>>