KMP习题集

添加链接描述模板题
剪花布条
AC代码

#include <bits/stdc++.h>
using namespace std;
void getNext(char p[],int Next[]){
    Next[0]=-1;
    int i=0,j=-1;
    int n=strlen(p);
    while(i<n){
        if(j==-1||p[i]==p[j]){
            i++;
            j++;
            Next[i]=j;
        }
        else
            j=Next[j];
    }
}
int KMP(char t[],char p[],int Next[]){
    int i=0,j=0;
    int n1=strlen(t);
    int n2=strlen(p);
    while(i<n1&&j<n2){
        if(j==-1||t[i]==p[j]){
            i++;
            j++;
        }
        else
            j=Next[j];
    }
    if(j==n2)
        return i;
    else
        return -1;
}
int main(){
    while(1){
        char t[1005],p[1005];
        int Next[1005];
        scanf("%s",t);
        if(t[0]=='#'){
            break;
        }
        scanf("%s",p);
        int len=strlen(t),cnt=1;
        getNext(p,Next);
        int loc=KMP(t,p,Next);
        if(loc==-1){
            printf("0\n");
            continue;
        }
        else if(loc==len){
            printf("1\n");
            continue;
        }
        else{
            while(1){
                int val=KMP(t+loc,p,Next);
                if(val==-1) break;
                loc=val+loc;
                cnt++;
            }

            printf("%d\n",cnt);
        }
    }
}

Oulipo
AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=1e6+5;
int cnt=0;
char p[10005],t[maxn];
int Next[10005];
void getNext(char p[],int Next[]){
	int i=0,j=-1;
	Next[0]=-1;
	int n=strlen(p);
	while(i<n){
		if(j==-1||p[i]==p[j]){
			i++;
			j++;
			Next[i]=j;
		}
		else
			j=Next[j];
	}
	return ;
}
void KMP(char t[],char p[],int Next[]){
	int i=0,j=0;
	int len1=strlen(t),len2=strlen(p);
	while(i<len1&&j<len2){
		if((j==-1||t[i]==p[j])&&j<len2-1){
			i++;
			j++;
		}
		else if(j==len2-1&&t[i]==p[j]){
			cnt++;
			j=Next[j];
		}
		else
			j=Next[j];
	}
	return ;
}
int main(){
	int num;
	scanf("%d",&num);
	while(num--){
	memset(t,'\0',sizeof(t));
	memset(p,'\0',sizeof(p));
	memset(Next,0,sizeof(Next));
	scanf("%s%s",p,t);
	cnt=0;
	getNext(p,Next);
	KMP(t,p,Next);
	printf("%d\n",cnt);
	}
	return 0;
}

Number Sequence 题解—>KMP
AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int p[10005],t[1000005];
int Next[10005];
void getNext(int p[],int Next[],int n){
	int i=0,j=-1;
	Next[0]=-1;
	while(i<n){
		if(j==-1||p[i]==p[j]){
			i++;
			j++;
			Next[i]=j;
		}
		else
			j=Next[j];
		//cout<<1<<endl;
	}
	return ;
}
int KMP(int t[],int p[],int Next[],int len1,int len2){
	int i=0,j=0;
	while(i<len1&&j<len2){
		if(j==-1||t[i]==p[j]){
			i++;
			j++;
		}
		else
			j=Next[j];
		//cout<<2<<endl;
	}
	if(j==len2)
	return i-j+1;
	else
	return -1;
}
int main(){
	int num;
	scanf("%d",&num);
	while(num--){
		int len1,len2;
		scanf("%d%d",&len1,&len2);
		for(int i=0;i<len1;i++){
			scanf("%d",&t[i]);
		}
		for(int i=0;i<len2;i++){
			scanf("%d",&p[i]);
		}
		getNext(p,Next,len2);
		printf("%d\n",KMP(t,p,Next,len1,len2));
	}
	return 0;
}

提升题
Simpsons’ Hidden Talents
简单评论一下:把两个字符串怎样连接成一个可以用Next解决的字符串
AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn1=5e4+5;
const int maxn=1e5+5;
char t[maxn],q[maxn];
char *p;
int Next[maxn];
void getNext(char *p,int Next[],int n){
	int i=0,j=-1;
	Next[0]=-1;
	while(i<n){
		if(j==-1||p[i]==p[j]){
			i++;
			j++;
			Next[i]=j;
		}
		else
			j=Next[j];
	}
	return ;
}
int main(){
    while(scanf("%s%s",t,q)!=EOF){
	int len1=strlen(t);
	int len2=strlen(q);
	p=strcat(t,q);
	int mi=min(len1,len2);
	int len=len1+len2;
	getNext(p,Next,len);
	int ans=Next[len];
	while(ans>mi){
		ans=Next[ans];
	}
	if(ans==0){
		printf("0\n");
	}
	else{
		for(int i=0;i<ans;i++){
			printf("%c",t[i]);
		}
		printf(" %d\n",ans);
	}
    }
    return 0;
}

Next数组含义剖析
AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e6+5;
char p[maxn];
int Next[maxn];
void getNext(char p[],int Next[],int n){
	Next[0]=-1;
	int i=0,j=-1;
	while(i<n){
		if(j==-1||p[i]==p[j]){
			i++;
			j++;
			Next[i]=j;
		}
		else
			j=Next[j];
	}
	return ;
}
int main(){
    int n,t=0;
    while(scanf("%d",&n),n){
	t++;
	scanf("%s",p);
	getNext(p,Next,n);
	printf("Test case #%d\n",t);
	for(int i=2;i<=n;i++){
		int len=i-Next[i];
		if(i!=len&&i%len==0){
			printf("%d %d\n",i,i/len);
		}
	}
	printf("\n");
    }
    return 0;
}

比上一题水一点的题目
AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e8+5;
char p[maxn];
int Next[maxn];
void getNext(char p[],int Next[],int n){
	Next[0]=-1;
	int i=0,j=-1;
	while(i<n){
		if(j==-1||p[i]==p[j]){
			i++;
			j++;
			Next[i]=j;
		}
		else
			j=Next[j];
	}
	return ;
}
int main(){
	while(scanf("%s",p)){
		int n=strlen(p);
		if(n==1&&p[0]=='.'){
			break;
		}
		getNext(p,Next,n);
		int len=n-Next[n];
		printf("%d\n",n%len==0?n/len:1);
	}
    return 0;
}

Next数组加强版(+回朔过程)
AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=2e5+5;
const int mod=10007;
char p[maxn];
int Next[maxn];
void getNext(char p[],int Next[],int n){
	Next[0]=-1;
	int i=0,j=-1;
	while(i<n){
		if(j==-1||p[i]==p[j]){
			i++;
			j++;
			Next[i]=j;
		}
		else
			j=Next[j];
	}
	return ;
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n,ans=0;
		scanf("%d%s",&n,p);
		getNext(p,Next,n);
		for(int i=1;i<=n;i++){
			int j=i;
			while(Next[j]!=-1){
				ans++;
				if(ans>=mod)
					ans%=mod;
				j=Next[j];
			}
		}
		printf("%d\n",ans);
	}
    return 0;
}

进阶题
Cyclic Nacklace
AC代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=1e5+5;
char p[maxn];
int Next[maxn];
int myabs(int x){
	return x>0?x:-x;
}
void getNext(char p[],int Next[],int n){
	Next[0]=-1;
	int i=0,j=-1;
	while(i<n){
		if(j==-1||p[i]==p[j]){
			i++;
			j++;
			Next[i]=j;
		}
		else
			j=Next[j];
	}
	return ;
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%s",p);
		int n=strlen(p);
		getNext(p,Next,n);
		int len=n-Next[n];
		if(n%len==0){
			if(n!=len)
			printf("0\n");
			else
				printf("%d\n",len);
		}
		else
		printf("%d\n",len-(n-n/len*len));
	}
    return 0;
}

附上大佬题解

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 长得好看会提高面试通过率吗? #
4609次浏览 48人参与
# 离家近房租贵VS离家远但房租低,怎么选 #
16917次浏览 137人参与
# 巨人网络春招 #
11559次浏览 230人参与
# 沪漂/北漂你觉得哪个更苦? #
1646次浏览 41人参与
# 你的实习产出是真实的还是包装的? #
3261次浏览 54人参与
# 春招至今,你的战绩如何? #
16231次浏览 147人参与
# MiniMax求职进展汇总 #
25294次浏览 322人参与
# HR最不可信的一句话是__ #
1118次浏览 33人参与
# AI面会问哪些问题? #
976次浏览 24人参与
# 你做过最难的笔试是哪家公司 #
1319次浏览 23人参与
# AI时代,哪个岗位还有“活路” #
2956次浏览 53人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152954次浏览 889人参与
# 简历第一个项目做什么 #
32209次浏览 364人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
8032次浏览 43人参与
# XX请雇我工作 #
51165次浏览 171人参与
# 简历中的项目经历要怎么写? #
311176次浏览 4273人参与
# 投格力的你,拿到offer了吗? #
178395次浏览 891人参与
# 你最满意的offer薪资是哪家公司? #
77017次浏览 375人参与
# AI时代,哪些岗位最容易被淘汰 #
64881次浏览 895人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187657次浏览 1123人参与
# 你怎么看待AI面试 #
180898次浏览 1320人参与
# 正在春招的你,也参与了去年秋招吗? #
364423次浏览 2642人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务