KMP算法题集
模板
#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 1e6 + 10;
const int MAXM = 1e3 + 10;
char a[MAXN], b[MAXM];
int next[MAXM], lena, lenb;
void get_next()
{
next[1] = 0; int j = 0;
_for(i, 2, lenb)
{
while(j > 0 && b[j + 1] != b[i]) j = next[j];
if(b[j + 1] == b[i]) j++;
next[i] = j;
}
}
void kmp()
{
int j = 0;
_for(i, 1, lena)
{
while(j > 0 && (j == lenb || b[j + 1] != a[i])) j = next[j];
if(b[j + 1] == a[i]) j++;
if(j == lenb) { printf("%d %d\n", i - lenb + 1, i); return; }
}
puts("NO");
}
int main()
{
scanf("%s%s", a + 1, b + 1);
lena = strlen(a + 1); lenb = strlen(b + 1);
get_next();
kmp();
return 0;
}
#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 1e6 + 10;
char a[MAXN], b[MAXN];
int next[MAXN], lena, lenb;
void get_next()
{
next[1] = 0; int j = 0;
_for(i, 2, lena)
{
while(j > 0 && a[j + 1] != a[i]) j = next[j];
if(a[j + 1] == a[i]) j++;
next[i] = j;
}
}
int kmp()
{
int res = 0, j = 0;
_for(i, 1, lenb)
{
while(j > 0 && a[j + 1] != b[i]) j = next[j];
if(a[j + 1] == b[i]) j++;
if(j == lena) { res++; j = next[j]; }
}
return res;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%s%s", a + 1, b + 1);
lena = strlen(a + 1); lenb = strlen(b + 1);
get_next();
printf("%d\n", kmp());
}
return 0;
}
重复子串结论
有一个结论。
对于字符串S[1~i],如果i % (i - next[i]) == 0,那么这个字符串就由很多个重复的子串构成(形如abababab)
每个循环节等于S[1~i-next[i]],循环节的个数为i / (i - next[i])
这个结论很好证明,用笔画一下就可以发现这个性质
#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 1e6 + 10;
char a[MAXN];
int next[MAXN], lena;
void get_next()
{
next[1] = 0; int j = 0;
_for(i, 2, lena)
{
while(j > 0 && a[j + 1] != a[i]) j = next[j];
if(a[j + 1] == a[i]) j++;
next[i] = j;
}
}
int main()
{
while(scanf("%s", a + 1))
{
if(a[1] == '.') break;
lena = strlen(a + 1);
get_next();
if(lena % (lena - next[lena]) == 0)
printf("%d\n", lena / (lena - next[lena]));
else puts("1");
}
return 0;
}
#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 1e6 + 10;
char a[MAXN];
int next[MAXN], lena;
void get_next()
{
next[1] = 0; int j = 0;
_for(i, 2, lena)
{
while(j > 0 && a[j + 1] != a[i]) j = next[j];
if(a[j + 1] == a[i]) j++;
next[i] = j;
}
}
int main()
{
scanf("%s", a + 1);
lena = strlen(a + 1);
get_next();
_for(i, 2, lena)
if(i % (i - next[i]) == 0 && i / (i - next[i]) > 1)
printf("%d %d\n", i, i / (i - next[i]));
return 0;
}
next数组应用
#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 1e6 + 10;
char a[MAXN];
int next[MAXN], lena;
void get_next()
{
next[1] = 0; int j = 0;
_for(i, 2, lena)
{
while(j > 0 && a[j + 1] != a[i]) j = next[j];
if(a[j + 1] == a[i]) j++;
next[i] = j;
}
}
int main()
{
while(~scanf("%s", a + 1))
{
lena = strlen(a + 1);
get_next();
int j = lena;
stack<int> s;
while(j) s.push(j), j = next[j];
while(!s.empty()) printf("%d ", s.top()), s.pop();
puts("");
}
return 0;
}
综合题
这道题不知道为什么一直A不了。先放着
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 1e4 + 10;
const int MAXM = 75 + 10;
char s[MAXN][MAXM], t[MAXN];
int next[MAXN], f[MAXN];
int n, m, r, c, j;
int get_r() //一行看作一个字符,很牛逼。
{
next[1] = 0;
for(int i = 2, j = 0; i <= n; i++)
{
if(j > 0 && strcmp(s[j + 1], s[i])) j = next[j];
if(!strcmp(s[j + 1], s[i])) j++;
next[i] = j;
}
return n - next[n];
}
int get_c()
{
memset(f, 0, sizeof(f));
_for(i, 1, n)
_for(len, 1, m)
REP(j, 0, m)
{
if(s[i][j] != s[i][j % len]) break; //这个操作要学学
if(j == m - 1) f[len]++;
}
_for(i, 1, m) //用桶这个思路很妙
if(f[i] == n)
return i;
}
int main()
{
scanf("%d%d", &n, &m);
_for(i, 1, n) scanf("%s", s[i]);
printf("%d\n", get_r() * get_c());
return 0;
}
KMP算法题集的更多相关文章
- 51nod 贪心算法题集
2070 最小罚款: 题意:初始有n元,每个任务有2个参数:t和w,<=t时刻前完成任务才可避免造成损失w.问:如何安排才能尽可能避免损失?一个任务执行时间是一个单位时间. 分析:任务按时间排个 ...
- 经典算法题每日演练——第七题 KMP算法
原文:经典算法题每日演练--第七题 KMP算法 在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的, 确实kmp算法还是有点饶人的,如果说红黑树 ...
- hihoCoder #1015 : KMP算法【KMP裸题,板子】
#1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...
- 串的模式之kmp算法实践题
给定两个由英文字母组成的字符串 String 和 Pattern,要求找到 Pattern 在 String 中第一次出现的位置,并将此位置后的 String 的子串输出.如果找不到,则输出“Not ...
- hdu 1711 KMP算法模板题
题意:给你两个串,问你第二个串是从第一个串的什么位置開始全然匹配的? kmp裸题,复杂度O(n+m). 当一个字符串以0为起始下标时.next[i]能够描写叙述为"不为自身的最大首尾反复子串 ...
- 51NOD欧姆诺姆和项链——KMP算法(非水题)
>>点击进入原题测试<< 思路:好久不见,今天要开始真正写题了.这个题之前我的理解有点问题,导致写了很久最终都是一直都只能过样例.需要注意的是输出中每一个“1”都是和别的输出相 ...
- 面试必备:高频算法题终章「图文解析 + 范例代码」之 矩阵 二进制 + 位运算 + LRU 合集
Attention 秋招接近尾声,我总结了 牛客.WanAndroid 上,有关笔试面经的帖子中出现的算法题,结合往年考题写了这一系列文章,所有文章均与 LeetCode 进行核对.测试.欢迎食用 本 ...
- 笔试算法题(52):简介 - KMP算法(D.E. Knuth, J.H. Morris, V.R. Pratt Algorithm)
议题:KMP算法(D.E. Knuth, J.H. Morris, V.R. Pratt Algorithm) 分析: KMP算法用于在一个主串中找出特定的字符或者模式串.现在假设主串为长度n的数组T ...
- LeetCode刷题--基础知识篇--KMP算法
KMP算法 关于字符串匹配的算法,最知名的莫过于KMP算法了,尽管我们日常搬砖几乎不可能去亲手实现一个KMP算法,但作为一种算法学习的锻炼也是很好的,所以记录一下. KMP算法是根据三位作者(D.E. ...
随机推荐
- Jenkins持续构建打包后端服务流程详解
背景运用场景及思路 1.为响应后端开发人员需求,提升项目开发过程效率,选择Jenkins持续构建,进行导包启动一键持续集成 思路: 使用jenkins自带,立即构建->SVN拉取代码,通过Jen ...
- Android scrollTo() scrollBy() Scroller解说及应用
版本号:1.0 日期:2014.6.17 2014.6.18 版权:© 2014 kince 转载注明出处 scrollTo() .scrollBy()及 Scroller在视图滑动中常常使用 ...
- codeforces Towers 题解
Little Vasya has received a young builder's kit. The kit consists of several wooden bars, the length ...
- 剑指offer面试题14(Java版):调整数组顺序使奇数位于偶数的前面
题目:输入一个整数数组.实现一个函数来调整该数组中数字的顺序.使得全部奇数位于数组的前半部分.全部偶数位于数组的后半部分. 1.基本实现: 假设不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每 ...
- ssh tunnel 上网
用DNS隧道实现免费上网 大多数机场.酒店之类场所,当你输入一个网址比如www.google.com时,会弹出一个页面要你输入帐号密码才能上网.这个时候DNS能正确解析,但是上网要付费认证. 可以通过 ...
- 机器学习 数据量不足问题----1 做好特征工程 2 不要用太多的特征 3 做好交叉验证 使用线性svm
来自:https://www.zhihu.com/question/35649122 其实这里所说的数据量不足,可以换一种方式去理解:在维度高的情况下,数据相对少.举一个特例,比如只有一维,和1万个数 ...
- Java-MyBatis:MyBatis XML 文件
ylbtech-Java-MyBatis:MyBatis XML 文件 1.返回顶部 1. Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大, ...
- 30.QT IDE编写
mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTe ...
- ubuntu下谷歌浏览器字体模糊解决方案
一般来说,这种问题应该是缺少字体造成的,因此重新安装字体就可以解决问题. 1.双系统下,查找Windows C盘下:Windows/font/???? ???可在3中查找相应字体 2.分别双击安装那两 ...
- Spark SQL概念学习系列之分布式SQL引擎
不多说,直接上干货! parkSQL作为分布式查询引擎:两种方式 除了在Spark程序里使用Spark SQL,我们也可以把Spark SQL当作一个分布式查询引擎来使用,有以下两种使用方式: 1.T ...