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. ...
随机推荐
- 基于Tags的简单内容推荐的实现
原来为了简单方便,自己小网站上的文章页的相关内容推荐就是从数据库里随机抽取数据来填充一个列表,所以一点相关性都没有,更本没有办法引导用户去访问推荐内容. 算法选择 如何能做到相似内容的推荐呢,碍于小网 ...
- [Design]Adobe CS6 2%错误问题
错误描述:FATAL: Payload '{3F023875-4A52-4605-9DB6-A88D4A813E8D} Camera Profiles Installer 6.0.98.0' info ...
- rails Installer之后的调整rails.bat等文件
rails Installer之后的调整rails.bat文件 出现系统找不到指定路径 学习了:http://www.jianshu.com/p/065355a731ee 修改rails.bat为 @ ...
- 安装ftp碰到的问题及解决方法
1 CRT显示乱码: 本地windows机器.改动SecureCRT的设置.找到"选项"->"会话选项"->"外观" ...
- Linux系统编程——多线程实现多任务
概述 每一个进程都拥有自己的数据段.代码段和堆栈段.这就造成进程在进行创建.切换.撤销操作时,须要较大的系统开销. 为了降低系统开销,从进程中演化出了线程.为了让进程完毕一定的工作.进程必须至少包括一 ...
- YunOS曙光初现----看好阿里云OS----阿冬专栏!!
阿里云os - YunOS 阿里云OS(YunOS)是阿里巴巴集团的智能手机操作系统,依托于阿里巴巴集团电子商务领域积累的经验和强大的云计算平台,基于LINUX开发. 魅族4阿里yun OS版已上市. ...
- Ubuntu+caffe训练cifar-10数据集
1. 下载cifar-10数据库 ciffar-10数据集包含10种物体分类,50000张训练图片,10000张测试图片. 在终端执行指令下载cifar-10数据集(二进制文件): cd ~/caff ...
- java代码实现python2中aes加密经历
背景: 因项目需要,需要将一个python2编写的aes加密方式改为java实现. 1.源python2实现 from Crypto.Cipher import AES from binascii i ...
- Android Handler学习笔记
已经习惯了挖坑不填,继续任性一下,周一到周五继续挖坑,每周六周日负责填坑. 1.从Android UI线程谈起 出于性能考虑,Android 中的UI操作并不是线程安全的,所以Android中规定只能 ...
- RecyclerView的刷新和加载更多
1.RecyclerView :出现也不知道多久了,没怎么使用过,上次写的笔记乱七八糟的,再次仔细的整理下. 使用需加入依赖 compile 'com.android.support:recyc ...