虽然说原理很好理解,但是代码理解了花费我一个下午的时间,脑阔痛

该注释的地方都标记了,希望以后看到这些代码我还能好好理解吧

学习的链接地址:https://www.cnblogs.com/teble/p/7280575.html

/*     Number Sequence     */
/*Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], ...... , a[K + M - 1] = b[M]. If there are more than one K exist, output the smallest one.
Input
The first line of input is a number T which indicate the number of cases. Each case contains three lines. The first line is two numbers N and M (1 <= M <= 10000, 1 <= N <= 1000000). The second line contains N integers which indicate a[1], a[2], ...... , a[N]. The third line contains M integers which indicate b[1], b[2], ...... , b[M]. All integers are in the range of [-1000000, 1000000].
Output
For each test case, you should output one line which only contain K described above. If no such K exists, output -1 instead.
Sample Input
2
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 1 3
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 2 1
Sample Output
6
-1*/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define MAXN 1000050
using namespace std;
//这道题看得出来需要使用到KMP排序
//虽然说我理解了排序原理,却不太懂得实现它
//对于我这种来说,最担心的的莫过于输入问题(所以最后干脆用int数组解决)
int a[MAXN], b[], _next[];
int repeat, i, n;
__int64 m; void makeNext()
{
int q=;//模板b字符串的临时下标,作为比较的后一位
int k=;//最大前后缀长度
_next[]=;//模板字符串第一个字符最大前后缀长度为0
while ( q<n )//遍历数组
{
if ( k== || b[k]==b[q] )//符合条件
{
++k,++q;//同时+1,判断下一位
if ( b[q]!=b[k] ) _next[q]=k;
else _next[q]=_next[k];//上下两句话改变next数组的值
} else k=_next[k];//如果不相等,将前标往前移动
}
/*数据检查for ( k=1 ; k<=n ; k++ )
{
cout<<b[k]<<' ';
}
cout<<endl;
for ( k=1 ; k<=n ; k++ )
{
cout<<_next[k]<<' ';
}
cout<<endl;*/
} int kmp()
{
int i, j;
for ( i=,j= ; i<=m&&j<=n ; )
{
if ( j== || a[i]==b[j] ) ++i,++j;
else j=_next[j];//如果不相等的话,将此时的j变小,相当于将b数组往右移动
//next数组提供,当a[]的后m个元素和b[]开头的前m个元素顺序相同时提供下标的服务
}
if ( j==n+ ) return i-n;//i是当前点,n是b[]的长度,返回的是初始点
else return -;//j==n+1的原因是a[]都被遍历完了,而b[]仍未遍历完
//只有当b[]都被遍历完了才算完整结束
} int main(void)
{
scanf("%d", &repeat);
while ( repeat-- )
{
scanf("%I64d%d",&m ,&n);
for ( i= ; i<=m ; i++ )
{
scanf("%d", &a[i]);
}
for ( i= ; i<=n ; i++ )
{
scanf("%d", &b[i]);
}
makeNext();
cout<<kmp()<<endl;
}
return ;
}

【2018.07.27】(字符串/找相同)学习KMP算法小记的更多相关文章

  1. 学习KMP算法的一点小心得

    KMP算法应用于 在一篇有n个字母的文档中 查找某个想要查找的长度为m的单词:暴力枚举:从文档的前m个字母和单词对比,然后是第2到m+1个,然后是第3到m+2个:这样算法复杂度最坏就达到了O(m*n) ...

  2. 子字符串查找之————关于KMP算法你不知道的事

    写在前面: (阅读本文前需要了解KMP算法的基本思路.另外,本着大道至简的思想,本文的所有例子都会做从头到尾的讲解) 作者翻阅了大量网上现有的KMP算法博客,发现广为流传的竟然是一种不完整的KMP算法 ...

  3. 字符串(2)KMP算法

    给你两个字符串a(len[a]=n),b(len[b]=m),问b是否是a的子串,并且统计b在a中的出现次数,如果我们枚举a从什么位置与匹配,并且验证是否匹配,那么时间复杂度O(nm), 而n和m的范 ...

  4. 学习 KMP 算法

    KMP 算法是用来处理字符串匹配问题的.也就是给你两个字符串,你需要回答:B 串是否是 A 串的子串(或 B 串在 A 串中出现的位置).比如,字符串 A = “ i am student ”, 字符 ...

  5. KMP算法小记

    Knuth-Morris-Pratt算法: 转载来自http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_ ...

  6. 扩展KMP算法小记

    参考来自<拓展kmp算法总结>:http://blog.csdn.net/dyx404514/article/details/41831947 扩展KMP解决的问题: 定义母串S和子串T, ...

  7. 【2018.07.28】(字符串/回文串)学习Manacher算法小记

    主要是应用在回文串啦,原理也理解了老半天,如果没有图片的话,我也看不太懂它的原理 学习的灵感来源来自于:https://segmentfault.com/a/1190000008484167 /* 最 ...

  8. 【2018.07.29】(深度优先搜索/回溯)学习DFS算法小记

    参考网站:https://blog.csdn.net/ldx19980108/article/details/76324307 这个网站里有动态图给我们体现BFS和DFS的区别:https://www ...

  9. 2018.07.17 HAOI2016 找相同字符(SAM)

    传送门 就是给两个字符串,让你求公共字串的个数. 本来大佬们都是用的广义后缀自动机,但我感觉后缀自动机已经可以做这道题了.我们对其中一个字串建出后缀自动机,然后用另外一个后缀自动机在上面统计贡献即可. ...

随机推荐

  1. 最近跟进一个CS项目,用到c#基础知识,准备开个分类记录一下

    C#在txt类文件中追加内容 string path = "test.txt";FileStream mystream = new FileStream(path, FileMod ...

  2. vue滚动分页加载以及监听事件处理

    <template> <div class="bodyContainer"> <div class="allContent" id ...

  3. 学习到目前,自己封装的db类和pdo类

    DB封装类 <?php class DBDA { public $host = "localhost"; public $uid = "root"; pu ...

  4. linux查看日志报错

    查看运行时错误: tail  -f  catalina.out   | grep   -C   10  'Exception'          10是行数: 单引号里面的是要查找的关键字:

  5. sql server行转列

    创建测试数据 学生表 Student create table Student(S# varchar(10),Sname nvarchar(10),Sage datetime,Ssex nvarcha ...

  6. SpringBoot properties和yml的区别

    一.先附一个yml文件的解析步骤 1.Maven依赖 <dependency> <groupId>org.yaml</groupId> <artifactId ...

  7. Linux系统Zip压缩和解压缩

    Linux系统可以使用Zip来压缩占用空间较大的文件以便进行文件传输,传输完成后再进行解压缩来获取原文件.Linux安装Zip的命令为 apt-get install zip 安装完成后,使用 zip ...

  8. Elasticsearch 最佳运维实践 - 总结(一)

    对于Elasticsearch的学习,需要清楚的明白它的每个核心概念,由浅入深的了解,才能更好的掌握这门技术.下面先简单罗列下Elasticsearch的核心概念: 一.Elasticsearch数据 ...

  9. 【FRDM-K64F学习笔记】使用ARM mbed和Keil MDK下载你的第一个程序

    FRDM-K64F开发平台采用MK64FN1M0VLL12微控制器.该控制器包含一个带有浮点单元的ARM Cortex-M4内核.其最高工作频率为120MHz,具有256KB的RAM.1MB闪存以及许 ...

  10. python 根据两个字段排序, 一个升序, 一个降序

    from collections import Counter c = Counter(input()) l=sorted(c.items(), key=lambda s:(-s[], s[])) ] ...