题目来自:http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2315188.html

KMP算法开始是判断字符串b是否是字符串a的子串,朴素的算法是枚举,时间复杂度O(m*n)

然后KMP(三个人名字的缩写)发明了KMP算法使时间复杂度降到了O(m+n)

但是<string.h>里面明明有一个函数是strstr(a,b)判断b是否为a的子串啊啊啊啊!!!

这个写得蛮好:http://blog.chinaunix.net/uid-27164517-id-3280128.html

以下仅限于个人理解:

a和b字符串匹配过程中,在j位置开始不匹配了

在0-j中寻找b0 b1 b2 ... bk = b(j-1-k) ... b(j-1)

当b与a字符串失配b应当从k+1个字符开始与a中刚刚失配的位置进行匹配

所以要确定k的值,而k的取值仅与j的位置有关,所以用next[]数组来盛放相应位置k的值

next(j) =   -1  起始位置

       k+1  0 <= k < j-1 失配时b应当重新开始匹配的位置

        0         其他

next[]数组的确立

void getNext(){
int k = -;
next[] = -;
int j = ;
int len = strlen(str);
while(j < len){
if(k == - || str[j] == str[k]){
k++;
j++;
next[j] = k;
}
else{
k = next[k];
}
}
}

http://poj.org/problem?id=3461

给a串和b串,求出b串中包含多少个a串

主要思路:

先对b进行next求解,然后对匹配到达最后进行计数……

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <stack>
#include <cctype>
#include <string>
#include <queue>
#include <map>
#include <set> using namespace std; const int INF = 0xffffff;
const double ESP = 10e-;
const double Pi = * atan(1.0);
const int MAXN = + ;
const long long MOD = ;
const int dr[] = {,,-,,-,,-,};
const int dc[] = {,,,-,,-,-,};
typedef long long LL; LL gac(LL a,LL b){
return b?gac(b,a%b):a;
}
char str[+];
char str1[MAXN];
int next[+]; void getNext(){
int k = -;
int j = ;
next[] = -;
int len = strlen(str);
while(j < len){
if(k == - || str[j] == str[k]){
j++;
k++;
next[j] = k;
}
else{
k = next[k];
}
}
} int main()
{
#ifndef ONLINE_JUDGE
freopen("inpt.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
int t;
scanf("%d",&t);
while(t--){
scanf("%s%s",str,str1);
getNext();
int cnt = ;
int len = strlen(str);
int len1 = strlen(str1);
int j = ;
int i = ;
while(i < len1){
if(j == - || str[j] == str1[i]){
i++;
j++;
}
else{
j = next[j];
}
if(j == len){
cnt++;
}
}
printf("%d\n",cnt);
}
return ;
}

http://poj.org/problem?id=2406

给你一个字符串s要求求出最大的 n 使 s = a^n (a是字串)

主要思路:

先对s串进行next求解,然后如果 len % (len-next[len]) == 0说明字符串恰由子串的n次方组成

则结果是  len / (len-next[len])

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm> using namespace std;
const int MAXN = 10e6 + ;
const int ESP = 10e-; char str[MAXN];
int next[MAXN]; void getNext(){
int k = -;
next[] = -;
int j = ;
int len = strlen(str);
while(j < len){
if(k == - || str[j] == str[k]){
k++;
j++;
next[j] = k;
}
else{
k = next[k];
}
}
} int main(){
// freopen("input.txt","r",stdin);
while(~scanf("%s",str)){
if(str[] == '.')
break;
getNext();
int len = strlen(str);
if(len % (len - next[len]) == ){
printf("%d\n",len / (len - next[len]));
}
else{
printf("1\n");
}
}
return ;
}

http://poj.org/problem?id=2752

给你一个字符串s,要求求出字符串从头开始到某个位置形成的子串a和从后面的某个位置到结尾的子串b,完全相同时输出a串的长度

主要思路:

先对s串进行next求解,从结尾开始依次寻找next[j] != 0 这说明最后几个和开头肯定是相同的,所以最后输出就好,ps:s串本身也符合条件

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm> using namespace std;
const int MAXN = + ;
const int ESP = 10e-; char str[MAXN];
int next[MAXN];
int q[MAXN]; void getNext(){
int k = -;
next[] = -;
int j = ;
int len = strlen(str);
while(j < len){
if(k == - || str[j] == str[k]){
k++;
j++;
next[j] = k;
}
else{
k = next[k];
}
}
} int main(){
// freopen("input.txt","r",stdin);
while(~scanf("%s",str)){
memset(next,,sizeof(next));
getNext();
int len = strlen(str);
int cnt = ;
int k = next[len];
q[cnt++] = len;
while(k){
q[cnt++] = k;
k = next[k];
}
for(int i = cnt-;i >= ;i--){
if(i != cnt-)
cout << ' ';
cout << q[i];
}
cout << endl;
}
return ;
}

http://poj.org/problem?id=2185

给你一个字符串矩阵,求出最小的子矩阵能把矩阵完全覆盖,求其面积

主要思路:

对字符矩阵的每行,每列进行next求解,求得其最小的字串能把所代表的字符串覆盖掉,得到行的最小公倍数,和列的最小公倍数,然后相乘求出面积。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <stack>
#include <cctype>
#include <string>
#include <queue>
#include <map>
#include <set> using namespace std; const int INF = 0xffffff;
const double ESP = 10e-;
const double Pi = * atan(1.0);
const int MAXN = + ;
const long long MOD = ;
const int dr[] = {,,-,,-,,-,};
const int dc[] = {,,,-,,-,-,};
typedef long long LL; LL gac(LL a,LL b){
return b?gac(b,a%b):a;
}
int lcm(int i,int j){
return i * j / gac(i,j);
}
char str[MAXN][];
int next[MAXN];
int n,m; void getR(int i){
int j = ;
int k = -;
next[] = -;
while(j < m){
if(k == - || str[i][j] == str[i][k]){
j++;
k++;
next[j] = k;
}
else{
k = next[k];
}
}
} void getC(int i){
int j = ;
int k = -;
next[] = -;
while(j < n){
if(k == - || str[j][i] == str[k][i]){
j++;
k++;
next[j] = k;
}
else{ k = next[k];
}
}
} int main()
{
#ifndef ONLINE_JUDGE
freopen("inpt.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
while(~scanf("%d%d",&n,&m)){
for(int i = ;i < n;i++){
scanf("%s",str[i]);
}
int r = ;
int c = ;
for(int i = ;i < n;i++){
getR(i);
int t = m - next[m];
r = lcm(r,t);
if(r >= m){
r = m;
break;
}
}
for(int i = ;i < m;i++){
getC(i);
int t = n - next[n];
c = lcm(c,t);
if(c >= n){
c = n;
break;
}
} printf("%d\n",r*c);
}
return ;
}

http://poj.org/problem?id=3080

求给出字符串共同拥有的字典序最小的长度最长的子串

解题思路:暴力,strstr函数直接水掉……2333333

#include <iostream>
#include <cstring>
#include <cstdio> using namespace std; char dna[][];
char str[];
char str1[]; int main()
{
// freopen("input.in","r",stdin);
int t;
int m;
scanf("%d",&t);
while(t--)
{
scanf("%d",&m);
for(int i = ;i < m;i++)
scanf("%s",dna[i]);
int maxnum = -0xfffff;
int len = strlen(dna[]);
bool flag = true;
for(int i = ;i < len;i++)
{
memset(str,,sizeof(str));
int t = ;
for(int j = ;j < len;j++)
{
bool flag2 = true;
if(i+j >= len)
break;
str[j] = dna[][i+j];
for(int k = ;k < m;k++)
{
if(strstr(dna[k],str) == NULL)
{
flag2 = false;
break;
}
}
if(flag2)
{
t++;
if(t == maxnum)
{
if(strcmp(str1,str) > )
strcpy(str1,str);
}
if(t > maxnum)
{
maxnum = t;
strcpy(str1,str);
}
flag = false;
}
else
break;
}
}
if(maxnum < || flag)
printf("no significant commonalities\n");
else
{
printf("%s\n",str1);
}
}
return ;
}

KMP poj的更多相关文章

  1. 字符串专题:KMP POJ 3561

    http://poj.org/problem?id=3461 KMP这里讲的不错next的求法值得借鉴 http://blog.sina.com.cn/s/blog_70bab9230101g0qv. ...

  2. 字符串KMP || POJ 2185 Milking Grid

    求一个最小矩阵,经过复制能够覆盖原矩阵(覆盖,不是填充,复制之后可以有多的) *解法:横着竖着kmp,求最大公倍数的做法是不对的,见http://blog.sina.com.cn/s/blog_69c ...

  3. KMP POJ 1961 Period

    题目传送门 /* 题意:求一个串重复出现(>1)的位置 KMP:这简直和POJ_2406没啥区别 */ /******************************************** ...

  4. KMP POJ 2406 Power Strings

    题目传送门 /* 题意:一个串有字串重复n次产生,求最大的n KMP:nex[]的性质应用,感觉对nex加深了理解 */ /************************************** ...

  5. KMP POJ 2752 Seek the Name, Seek the Fame

    题目传送门 /* 题意:求出一个串的前缀与后缀相同的字串的长度 KMP:nex[]就有这样的性质,倒过来输出就行了 */ /************************************** ...

  6. Kuangbin 带你飞 KMP扩展KMP Manacher

    首先是几份模版 KMP void kmp_pre(char x[],int m,int fail[]) { int i,j; j = fail[] = -; i = ; while (i < m ...

  7. POJ 3450 后缀数组/KMP

    题目链接:http://poj.org/problem?id=3450 题意:给定n个字符串,求n个字符串的最长公共子串,无解输出IDENTITY LOST,否则最长的公共子串.有多组解时输出字典序最 ...

  8. POJ 2406 KMP/后缀数组

    题目链接:http://poj.org/problem?id=2406 题意:给定一个字符串,求由一个子串循环n次后可得到原串,输出n[即输出字符串的最大循环次数] 思路一:KMP求最小循环机,然后就 ...

  9. 【poj 2185】Milking Grid(字符串--KMP+问题分解)

    题意:给定一个由字符组成的矩阵,求出它的面积最小的覆盖矩阵.(感觉应该是可重叠的......* (・ω・)っ) 解法:KMP.行列互不影响,可以问题分解.先求出每一行的最小重复串,利用kmp中的nex ...

随机推荐

  1. Ural 1086 - Cryptography

    While preparing this problem set the jury has run into the following problem: it was necessary to se ...

  2. 单实例支撑每天上亿个请求的SSDB

    SSDB 是一个 C++ 开发的 NoSQL 存储服务器, 支持 zset, map 数据结构, 可替代 Redis, 特别适合存储集合数据. SSDB 被开发和开源出来后, 已经在生产环境经受了3个 ...

  3. 【一】仿微信飞机大战cocos2d-x3.0rc1

    參考 [偶尔e网事] 的 [cocos2d-x入门实战]微信飞机大战  cocos2dx 2.0版本号,偶尔e网事他写的很具体,面面俱到,大家很有必要看下.能够通过以下链接跳转: cocos2d-x入 ...

  4. R语言RJava安装步骤

     1.安装JDK 2.在R下运行install.packages("rJava") 2.环境变量设置 CLASSPATH=xxx\R-xxx\library\rJava\jri ...

  5. android 应用静默自启动的解决方法

    一个apk完全的自动静默启动目前不能实现,所以就用到了Activity的一个方法activity.moveTaskToBack(boolean),这个方法就是可以退出应用到后台而不是finish()退 ...

  6. 在SSH框架中使用Spring的好处(转)

    以下是我总结下今天笔试中SSh中的总结: 在SSH框架中spring充当了管理容器的角色.我们都知道Hibernate用来做持久层,因为它将JDBC做了一个良好的封装,程序员在与数据库进行交互时可以不 ...

  7. PHP - 目录与文件

    第6章 目录与文件 学习要点: 1.目录操作 2.磁盘.目录和文件计算 3.文件处理 将相关的数据组织为文件和目录等实体,这一直是计算环境的核心概念.出于这个原因,程序员需要有一种方法来获得关于文件和 ...

  8. Ormlite自定义db的位置和自动更新问题

    先说说以下为测试代码,有点乱,大家讲究着看.以下例子都是采用的ormlite的框架. 第一步,自定义数据库的位置: 建议一个类DatabaseHelper 继承 OrmLiteSqliteOpenHe ...

  9. wcf 出现 IsContentTypeSupported 错误

    查看添加的服务地址是不是https开头的,而 *.config 文件里面自动添加的链接变成了http,当前的bindbing类型为basicHttpBinding, 解决方法:在config文件里面手 ...

  10. 配置Eclipse使用外部Maven

    当集成Maven时,Eclipse会安装上一个内嵌的Maven, 这个内嵌的Maven通常会比较新,但不一定很稳定,而且往往也会和命令行使用的Maven不是同一个版本.这里又会出现两个潜在的问题:首先 ...