poj kmp入门几题 mark

来源:互联网 发布:淘宝 买摩托车 编辑:程序博客网 时间:2024/05/20 13:40

poj 3461:找模式串在匹配串中出现的次数

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <string>#include <vector>#include <stack>#include <bitset>#include <set>#include <list>#include <deque>#include <time.h>#include <map>#include <queue>#define pi acos(-1)#define ll long longusing namespace std;const int N=1000020;///字符串下标从0开始 nxt数组下标从1开始 int nxt[N];char S[N],T[N];///T为模式串 int slen,tlen;void getnxt(){int j=0,k=-1;nxt[0]=-1;while(j<tlen){if(k==-1 || T[j]==T[k]) nxt[++j]=++k;else k=nxt[k];} } int kmpidx(){///模式串T在主串S中首次出现的位置 0 idxint i=0,j=0;while(i<slen && j<tlen){if(j==-1 || S[i]==T[j]) ++i,++j;else j=nxt[j];}if(j==tlen) return i-tlen;else return -1;}int kmpcount(){///模式串T在主串S中出现的次数int ans=0,j=0;for(int i=0;i<slen;++i){while(j>0 && S[i]!=T[j]) j=nxt[j];if(S[i]==T[j]) ++j;if(j==tlen) ans++,j=nxt[j];}return ans;}int main(){int t;scanf("%d",&t);while(t--){scanf("%s %s",T,S);tlen=strlen(T),slen=strlen(S);getnxt();//for(int i=1;i<tlen;++i) printf("%d ",nxt[i]); //puts("");//printf("模式串T在主串S中首次出现的位置是: %d\n",kmpidx());//printf("模式串T在主串S中出现的次数是: %d\n",kmpcount());printf("%d\n",kmpcount());}return 0;}

poj 2752 给一个串,找出所有既是前缀又是后缀的子串,升序输出子串长度

考察 对nxt数组的理解 打印nxt数组可以发现

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <string>#include <vector>#include <stack>#include <bitset>#include <set>#include <list>#include <deque>#include <time.h>#include <map>#include <queue>#define pi acos(-1)#define ll long longusing namespace std;const int N=1000020;///字符串下标从0开始 nxt数组下标从1开始 int nxt[N];char S[N],T[N];///T为模式串 int slen,tlen;void getnxt(){int j=0,k=-1;nxt[0]=-1;while(j<tlen){if(k==-1 || T[j]==T[k]) nxt[++j]=++k;else k=nxt[k];}}int main(){///while(scanf("%s",T)==1){tlen=strlen(T),slen=strlen(S);getnxt();//for(int i=1;i<=tlen;++i) printf("%d %d\n",i,nxt[i]);vector<int> vs;vs.push_back(tlen);int tmp=tlen;while(nxt[tmp]!=0){vs.push_back(nxt[tmp]);tmp=nxt[tmp];}reverse(vs.begin(),vs.end());vector<int>::iterator it=vs.begin();printf("%d",*it);for(++it;it!=vs.end();++it) printf(" %d",*it);puts("");}return 0;}


poj 2406 

给一个串,要你找出最大的n,使得这个串是由n个相同的子串拼接而成的

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <string>#include <vector>#include <stack>#include <bitset>#include <set>#include <list>#include <deque>#include <time.h>#include <map>#include <queue>#define pi acos(-1)#define ll long longusing namespace std;const int N=1000020;///字符串下标从0开始 nxt数组下标从1开始 int nxt[N];char S[N],T[N];///T为模式串 int slen,tlen;void getnxt(){int j=0,k=-1;nxt[0]=-1;while(j<tlen){if(k==-1 || T[j]==T[k]) nxt[++j]=++k;else k=nxt[k];}}int main(){///while(scanf("%s",T)==1 && T[0]!='.'){tlen=strlen(T);getnxt();//for(int i=1;i<=tlen;++i) printf("%d %d\n",i,nxt[i]);int ans=(tlen%(tlen-nxt[tlen])==0)?tlen/(tlen-nxt[tlen]):1;printf("%d\n",ans);}return 0;}

一个wa点及其nxt数组

aabaabaabaabaab
0 1 0 1 2 3 4 5 6 7 8 9 10 11 12





原创粉丝点击