模板

caioj 1177 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;
}

caioj 1460: 【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;
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])

这个结论很好证明,用笔画一下就可以发现这个性质

caioj 1457: 【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;
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;
}

caioj 1458: 【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;
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数组应用

caioj 1459: 【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;
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;
}

综合题

poj 2185

这道题不知道为什么一直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算法题集的更多相关文章

  1. 51nod 贪心算法题集

    2070 最小罚款: 题意:初始有n元,每个任务有2个参数:t和w,<=t时刻前完成任务才可避免造成损失w.问:如何安排才能尽可能避免损失?一个任务执行时间是一个单位时间. 分析:任务按时间排个 ...

  2. 经典算法题每日演练——第七题 KMP算法

    原文:经典算法题每日演练--第七题 KMP算法 在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的, 确实kmp算法还是有点饶人的,如果说红黑树 ...

  3. hihoCoder #1015 : KMP算法【KMP裸题,板子】

    #1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...

  4. 串的模式之kmp算法实践题

    给定两个由英文字母组成的字符串 String 和 Pattern,要求找到 Pattern 在 String 中第一次出现的位置,并将此位置后的 String 的子串输出.如果找不到,则输出“Not ...

  5. hdu 1711 KMP算法模板题

    题意:给你两个串,问你第二个串是从第一个串的什么位置開始全然匹配的? kmp裸题,复杂度O(n+m). 当一个字符串以0为起始下标时.next[i]能够描写叙述为"不为自身的最大首尾反复子串 ...

  6. 51NOD欧姆诺姆和项链——KMP算法(非水题)

    >>点击进入原题测试<< 思路:好久不见,今天要开始真正写题了.这个题之前我的理解有点问题,导致写了很久最终都是一直都只能过样例.需要注意的是输出中每一个“1”都是和别的输出相 ...

  7. 面试必备:高频算法题终章「图文解析 + 范例代码」之 矩阵 二进制 + 位运算 + LRU 合集

    Attention 秋招接近尾声,我总结了 牛客.WanAndroid 上,有关笔试面经的帖子中出现的算法题,结合往年考题写了这一系列文章,所有文章均与 LeetCode 进行核对.测试.欢迎食用 本 ...

  8. 笔试算法题(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 ...

  9. LeetCode刷题--基础知识篇--KMP算法

    KMP算法 关于字符串匹配的算法,最知名的莫过于KMP算法了,尽管我们日常搬砖几乎不可能去亲手实现一个KMP算法,但作为一种算法学习的锻炼也是很好的,所以记录一下. KMP算法是根据三位作者(D.E. ...

随机推荐

  1. Django安装部署

    MVC模式说明 Model:是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据 View: 是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的 Controlle ...

  2. Supervisor 从入门到放弃

    前言 Supervisor是一个客户端/服务器系统,允许其用户在类UNIX操作系统上控制许多进程.(官方解释) 简单点来讲,就是一个监控脚本运行的工具,不过他可以统一化管理,laravel的队列文档上 ...

  3. zookeeper核心概念

    可以借鉴:https://blog.csdn.net/junchenbb0430/article/details/77583955 zookeeper的组成部分: 1. Leader:起主导集群的作用 ...

  4. Android Drawable 那些不为人知的高效使用方法

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/43752383,本文出自:[张鸿洋的博客] 1.概述 Drawable在我们平时的 ...

  5. maven 创建web项目出错

    错误的信息: .m2/repository/org/apache/maven/archetypes/maven-archetype-webapp/maven-metadata-central.xml ...

  6. web后台知识点整理

    五.JEE 适用于创建server端的大型的软件服务系统 1. JEE : JAVA  PLATFORM  ENTERPRISE  DEDITON 2.是一个规范集.技术集.框架集(API集) 一种技 ...

  7. 2014.08.04,读书,读书笔记-《Matlab概率与数理统计分析》-第1章 MATLAB的数据基础

    第1章 MATLAB数据基础 虽然一直间或使用MATLAB,但从来没有系统的学习过,现在开始也不晚.先对几个重点或者平时忽略的要点做下笔记. %后的所有文字为注释,多条命令可以放在一行,但要用逗号或分 ...

  8. idea 中web项目 用自带tomcat启动问题,

    严重: Exception sending context initialized event to listener instance of class com.zenointel.logserve ...

  9. 0x08 总结与练习

    1:前面已经搞好了. 2:poj2965 这种开关问题一个点要么点一次要么不点,枚举所有点的方案实行即可 #include<cstdio> #include<iostream> ...

  10. $scope angular在controller之外调用

    1.定义 var m = angular.module('ddd',[]); m.controller('ctrl',['$scope',function ($scope) { }]); 2.外部调用 ...