主要还是KMP算法,上学期没学,只是考前抱了抱佛脚,也没怎么弄明白.
先放代码:

//KMP
#include <bits/stdc++.h>//万能头
using namespace std;
string s,t;//s文本串,t模式串
//用char数组比较符合习惯,但是想试试string类
int nxt[100002];//在全局变量区,一般这个数组会初始化为全0
//getNext函数实际上就是让t自己与自己进行一个匹配.
void getNext(string& t)//一开始用的string* t,但好像不可以?
{
nxt[0]=-1;
int k=-1,j=0;
while(j<t.length())//最初写的t.length()-1,答案不对,见main中的解释
{
if(k==-1||t[k]==t[j])//匹配成功,往后继续
{
j++;k++;
//先++再给nxt数组赋值,因为我是按这个位置之前的字符串(不包括当前位置)的最长前后缀长度为此位置的nxt值
nxt[j]=k;
}
else k=nxt[k];
//意思是如果串的前后缀匹配到这里开始不等了,就寻找前面串里是否还有更小的前后缀(后面会图解)
}
} int KMP(string& s,string& t)//同样不知道为什么得用&引用才不报错
{
int ls = s.length(),lt = t.length();
int i=-1,j=-1;
while(i<ls)
{
if(s[i]==t[j]||j==-1)
{
i++; j++;
}
else j = nxt[j];//匹配不上就把t串右移
if(j==lt)//t被全部匹配上了
{
printf ("%d\n",i-lt+1);
j = nxt[j];//继续找下一个匹配上的位置
}
}
if(j<lt) return -1;//最后没匹配上就返回-1
}
int main()
{
cin>>s>>t;//太久不打,最初串流符号都打返了
getNext(t);
KMP(s,t);
for(int i=1;i<=t.length();i++) printf("%d ",nxt[i]);
//最后一行输出border,似乎是nxt,但又不真的是nxt
//因为我的nxt其实求的是上一位的border...
//所以从1号下标开始输出,这时候最后那个border会出现缺失(为0)情况
//因为根本没算它,就是初始值.所以我在求nxt的时候又多求了一位
//也就出现了getNxt函数中的t.length()没有减1...
}

我的理解:
①求nxt值时,刚开始很明显是要找到和开头一样的字母的第一个位置.
于是就有k=-1,j=0,先++再开始比较,此时k是0,j是1,如果匹配不成功,k就不断回到-1(因为nxt[0]是-1),j继续往后走,直到找到串的开头字母.
②然后就进行匹配成功的操作:k++,j++,如果匹配成功就继续比较下一位,如果失败就如下图所示:
绿色(深绿加浅绿)代表已经匹配好的t的子串,但是当k,j再右移的时候,两个"指针"指向的字母开始不同,这时候就寻找之前匹配过的串,看看有没有更短些的前后缀.也就出现了如图所示的k=nxt[k].

再看KMP算法的过程:
我觉得图已经很清晰了,后面看如果不懂的话再加文字吧…

[数据结构][洛谷]P3375模板题 KMP的更多相关文章

  1. 洛谷P3375 [模板]KMP字符串匹配

    To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...

  2. 【AC自动机】洛谷三道模板题

    [题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...

  3. 【最大流ISAP】洛谷P3376模板题

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  4. 【后缀数组】洛谷P3809模板题

    题目背景 这是一道模板题. 题目描述 读入一个长度为 n n n 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置. ...

  5. LCA算法倍增算法(洛谷3379模板题)

    倍增(爬树)算法,刚刚学习的算法.对每一个点的父节点,就记录他的2k的父亲. 题目为http://www.luogu.org/problem/show?pid=3379 第一步先记录每一个节点的深度用 ...

  6. 【后缀自动机】洛谷P3804模板题

    题目描述 给定一个只包含小写字母的字符串SSS, 请你求出 SSS 的所有出现次数不为 111 的子串的出现次数乘上该子串长度的最大值. 输入输出格式 输入格式: 一行一个仅包含小写字母的字符串SSS ...

  7. KMP字符串匹配 模板 洛谷 P3375

    KMP字符串匹配 模板 洛谷 P3375 题意 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.(如果 ...

  8. 洛谷 P3375 【模板】KMP字符串匹配 || HDU 1686 Oulipo || kmp

    HDU-1686 P3375 kmp介绍: http://www.matrix67.com/blog/archives/115 http://www.cnblogs.com/SYCstudio/p/7 ...

  9. 洛谷 P4148 简单题 KD-Tree 模板题

    Code: //洛谷 P4148 简单题 KD-Tree 模板题 #include <cstdio> #include <algorithm> #include <cst ...

  10. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

随机推荐

  1. Kafka QuickStart

    环境版本 操作系统:CentOS release 6.6 (Final) java版本: jdk1.8 kafka 版本: kafka_2.11-1.1.1.tgz 安装kafka 1. 下载压缩包, ...

  2. PAT (Basic Level) Practice 1011 A+B 和 C 分数 15

    给定区间 [−231,231] 内的 3 个整数 A.B 和 C,请判断 A+B 是否大于 C. 输入格式: 输入第 1 行给出正整数 T (≤10),是测试用例的个数.随后给出 T 组测试用例,每组 ...

  3. PAT (Basic Level) Practice 1010 一元多项式求导 分数 25

    设计函数求一元多项式的导数.(注:xn(n为整数)的一阶导数为nxn−1.) 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过 1000 的整数).数字间以空格分隔. 输出格式: ...

  4. python中类与对象的命名空间(静态属性的陷阱)、__dict__ 和 dir() 在继承中使用说明

    1. 面向对象的概念 1)类是一类抽象的事物,对象是一个具体的事物:用类创建对象的过程,称为实例化. 2)类就是一个模子,只知道在这个模子里有什么属性.什么方法,但是不知道这些属性.方法具体是什么: ...

  5. P3834 【模板】可持久化线段树 2

    P3834 主席树模板,求区间第k小. 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define lc tr[i].ch[0] ...

  6. 220722 T4 求和 /P4587 [FJOI2016]神秘数 (主席树)

    好久没打主席树了,都忘了怎么用了...... 假设我们选了一些数能构成[0,x]范围内的所有值,下一个要加的数是k(k<=x+1),那么可以取到[0,x+k]内的所有取值,所以有一种做法: 对于 ...

  7. Linux-->文件目录作用查询

    Linux的目录结构 在Linux中他的根目录都是决定好的无法改名,并且每一个目录他的作用都是决定好的 在Linux中一切都是文件!,Linux会把所有的硬件都映射成文件 / 代表根目录 /bin / ...

  8. 测试杂谈——一条SQL引发的思考(二)

    在前段时间,曾写过一篇关于SQL问题的文章,测试杂谈--一条SQL引发的思考(一). 今天这篇,算是个问题记录吧,问题并不复杂,但对于测试同学而言,确实是个需要关注的点. 问题分析 最近在日常工作中, ...

  9. LeetCode题目答案及理解汇总(持续更新)

    面试算法题 dfs相关 全排列 #include<bits/stdc++.h> using namespace std; const int N = 10; //用一个path数组来存储每 ...

  10. 齐博x1细节优化,自定义二、三、四维字段支持自定描述

    如下图所示,之前自定义字估中的二.三.四维字段,不支持自定义描述,导致用户输入的时候,不知道该输入什么信息内容.只有站长自己才知道. 现在支持自定义描述,及设置文本或数字.方便引导用户输入相应的信息内 ...