字符串KMP小结
来源:互联网 发布:网络电视盒能收多少台 编辑:程序博客网 时间:2024/06/05 05:05
一:返回模式串在主串的下标BF与KMP与KMP1
#include <iostream>#include<malloc.h>#include<cstdio>using namespace std;#define MaxSize 100int next[MaxSize];int nextval[MaxSize];typedef struct{ char data[MaxSize]; int length;} SqString;void Assign(SqString &s,char cstr[]){ int i; for(i=0; cstr[i]!='\0'; i++) s.data[i]=cstr[i]; s.length=i;}int BF(SqString s,SqString t){ int i=0,j=0; while(i<s.length&&j<t.length) { if(s.data[i]==t.data[j]) { i++; j++; } else { i=i-j+1; j=0; } } if(j>=t.length) return i-t.length; else return -1;}void GetNext(SqString t,int next[]){ int i=0,j=-1; next[0]=-1; while(i<t.length-1) { if(j==-1||t.data[i]==t.data[j]) { i++; j++; next[i]=j; } else j=next[j]; }}int KMP(SqString s,SqString t){ int i=0,j=0; GetNext(t,next); while(i<s.length&&j<t.length) { if(j==-1||s.data[i]==t.data[j]) { i++; j++; } else j=next[j]; } if(j>=t.length) return i-t.length; else return -1;}void GetNextVal(SqString t,int next[]){ int i=0,j=-1; nextval[0]=-1; while(i<t.length) { if(j==-1||t.data[i]==t.data[j]) { i++; j++; if(t.data[i]!=t.data[j]) nextval[i]=j; else nextval[i]=nextval[j]; } else j=nextval[j]; }}int KMP1(SqString s,SqString t){ int i=0,j=0; GetNextVal(t,next); while(i<s.length&&j<t.length) { if(j==-1||s.data[i]==t.data[j]) { i++; j++; } else j=nextval[j]; } if(j>=t.length) return i-t.length; else return -1;}int main(){ SqString s,t; Assign(s,"abcdefghi"); Assign(t,"cdef"); printf("用BF算法返回匹配下标:"); printf("%d\n",BF(s,t)); printf("用KMP算法返回匹配下标:"); printf("%d\n",KMP(s,t)); printf("用修正后的KMP算法返回匹配下标:"); printf("%d\n",KMP1(s,t)); return 0;}
二:返回模式串在主串中出现的次数
如图:
#include <iostream>#include<malloc.h>#include<cstdio>using namespace std;#define MaxSize 100int next[MaxSize];int nextval[MaxSize];int n;typedef struct{ char data[MaxSize]; int length;} SqString;void Assign(SqString &s,char cstr[]){ int i; for(i=0; cstr[i]!='\0'; i++) s.data[i]=cstr[i]; s.length=i;}int BF(SqString s,SqString t){ int i=0,j=0,n=0; while(i<s.length&&j<t.length) { if(s.data[i]==t.data[j]) { i++; j++; } else { i=i-j+1; j=0; } ///仅仅在此部分做了处理 if(j>=t.length) { n++; i=i-j+1; j=0; } } return n;}void GetNext(SqString t,int next[]){ int i=0,j=-1; next[0]=-1; while(i<t.length-1) { if(j==-1||t.data[i]==t.data[j]) { i++; j++; next[i]=j; } else j=next[j]; }}int KMP(SqString s,SqString t){ int i=0,j=0,n=0; GetNext(t,next); while(i<s.length&&j<t.length) { if(j==-1||s.data[i]==t.data[j]) { i++; j++; } else j=next[j]; ///仅仅在此部分做了处理 if(j>=t.length) { n++; i=i-j+1; j=0; } } return n;}void GetNextVal(SqString t,int next[]){ int i=0,j=-1; nextval[0]=-1; while(i<t.length) { if(j==-1||t.data[i]==t.data[j]) { i++; j++; if(t.data[i]!=t.data[j]) nextval[i]=j; else nextval[i]=nextval[j]; } else j=nextval[j]; }}int KMP1(SqString s,SqString t){ int i=0,j=0,n=0; GetNextVal(t,next); while(i<s.length&&j<t.length) { if(j==-1||s.data[i]==t.data[j]) { i++; j++; } else j=nextval[j]; ///仅仅在此部分做了处理 if(j>=t.length) { n++; i=i-j+1; j=0; } } return n;}int main(){ SqString s,t; Assign(s,"abcdefghicdefcdef"); Assign(t,"cdef"); printf("用BF算法返回匹配次数:"); printf("%d\n",BF(s,t)); printf("用KMP算法返回匹配次数:"); printf("%d\n",KMP(s,t)); printf("用修正后的KMP算法返回匹配次数:"); printf("%d\n",KMP1(s,t)); return 0;}
三:最小循环节,即最大的循环次数
如图:POJ2406
len-next[len]是最小循环节,而len/(len-next[len])是最大的循环次数
#include <iostream>#include<string.h>#include<cstdio>using namespace std;char t[1000000];int next[1000000];void getnext(){ int i=0,j=-1; next[0]=-1; while(i<strlen(t)) { if(j==-1||t[i]==t[j]) { i++; j++; next[i]=j; } else j=next[j]; }}int main(){ while(scanf("%s",t)) { if(t[0]=='.') break; int len=strlen(t); getnext(); if(len%(len-next[len])==0) printf("%d\n",len/(len-next[len])); else printf("1\n"); } return 0;}
字符串的所有大小循环节以及他们的周期POJ1961
如图:
///i-next[i]是循环节的长度
void getnext(const char *t)///有无参数都行
#include <iostream>#include<string.h>#include<cstdio>using namespace std;char t[1000000];int next[1000000];int len;void getnext(const char *t)///无参数也行{ int i=0,j=-1; next[0]=-1; while(i<strlen(t)) { if(j==-1||t[i]==t[j]) { i++; j++; next[i]=j; } else j=next[j]; }}int main(){ int ant=0; while(scanf("%d",&len)&&len) { scanf("%s",t); getnext(t);///无参数也行 printf("Test case #%d\n",++ant); for(int i=1;i<=len;i++) { if(i%(i-next[i])==0&&(i!=i-next[i])) ///如果有多个循环节 printf("%d %d\n",i,i/(i-next[i])); } printf("\n"); } return 0;}
哈哈
0 0
- 字符串KMP小结
- 【字符串】 KMP算法小结(通俗易理解)
- KMP 小结
- KMP小结
- KMP小结
- KMP小结
- KMP小结
- KMP小结
- KMP小结
- KMP小结
- pku kmp题目小结
- KMP算法小结
- KMP算法小结
- KMP算法小结
- KMP算法小结
- KMP算法小结
- KMP算法小结
- KMP算法小结 2
- ORACLE 开启归档日志及更改归档路径
- Java实现Session模块来处理Token
- Navicat 常用快捷键
- finished with non-zero exit value 1
- Tricks(三十五)—— 内积的极简实现
- 字符串KMP小结
- iOS 8 Auto Layout界面自动布局系列3-使用代码添加布局约束
- javaScript对象基础
- 剑指offer系列之57:对称二叉树的判断
- 关于SVM一篇比较全介绍的博文
- AR资料汇总
- 构造器与垃圾回收器
- left join on 和where条件的放置
- Android官方MVP架构示例项目解析