标签:
c.
/* kmp模板 */ #include<iostream> #include<stdio.h> #include<string.h> using namespace std; #define MAXN 1024//字符串长度 int _next[MAXN]; void GetNext(char t[]){//求next数组 int j,k,len; j=0;//从0开始,首先求_next[1] k=-1;//比较指针 _next[0]=-1;//初始值-1 len=strlen(t); while(j<len){ if(k==-1||t[j]==t[k]){//指针到头了,或者相等 ++j; ++k; _next[j]=k;//此句可由优化替代 /*优化(求匹配位置时可用) if(t[j]!=t[k])_next[j]=k; else _next[j]=_next[k]; //*/ } else k=_next[k]; } } int KMPIndex(char s[],char t[]){//求子串首次出现在主串中的位置 int i,j,lens,lent; i=j=0; lens=strlen(s); lent=strlen(t); while(i<lens&&j<lent){ if(j==-1||s[i]==t[j]){ ++i; ++j; } else j=_next[j]; } if(j>=lent)return i-lent; else return -1; } int KMPCount(char s[],char t[]){//统计子串在主串中的出现次数,可重叠 int i,j,lens,lent,cnt; i=j=0; lens=strlen(s); lent=strlen(t); cnt=0; while(i<lens){ if(j==-1||s[i]==t[j]){ ++i; ++j; } else j=_next[j]; if(j==lent)++cnt; } return cnt; } void KMPCount2(char t[]){//统计单串中从某个位置以前有多少重复的串 int i,lent,tmp; lent=strlen(t); for(i=2;i<=lent;++i){ tmp=i-_next[i];//tmp是0...i-1这一串的最小循环节长度 if(i%tmp==0&&i/tmp>1) printf("\t位置:%d 个数:%d\n",i,i/tmp); } } int main(){ char str1[MAXN],str2[MAXN]; int i,len2; printf("输入主串、子串:"); while(~scanf("%s%s",str1,str2)){ GetNext(str2);//求子串的next数组 //输出next数组的值 printf("next:"); len2=strlen(str2); for(i=0;i<=len2;++i) printf("%d ",_next[i]); printf("\n"); printf("首次出现位置:%d\n",KMPIndex(str1,str2)); printf("子串在主串中的出现次数:%d\n",KMPCount(str1,str2)); printf("子串中的重复串:\n"); KMPCount2(str2); printf("输入主串、子串:"); } return 0; }
标签:
原文地址:http://www.cnblogs.com/bofengyu/p/5153943.html