kmp的c++代码
2016-08-05 17:36
381 查看
个人心得:说实话第一次接触kmp算法,确实是不太好理解,反正我是的,大神就比不了了
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
。
kmp算法主要分两个部分实现:第一个部分,就是去求next数组的值;
第二个部分,就是两个字符串去匹配;
next数组是什么意思了,我个人认为就是当长度为j时,该字符串的前缀与后缀相等的长度;
![](http://img.blog.csdn.net/20131129230609062?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHVtaW4zMzA3NzQyMzM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
例如:t[]="abcabc";
j=0,next[0]=-1;
j=1,字符串为"a",next[1]=0;
j=2,字符串为"ab",next[2]=0;
j=3,字符串为"abc",next[3]=0;
j=4,字符串为"abca",next[4]=1;
j=5,字符串为"abcab",next[5]=2;
最后当j==strlen(t),next[j]=3,表示该字符串前缀与后缀相等的最大长度;
实现代码:
最后就是匹配了,有几种不同的要求
第一:求在s串中出现的位置
第二种:求周期
例如:ababab 周期为3;
因为我们已经说了:最后当j==strlen(t),next[j]=3,表示该字符串前缀与后缀相等的最大长度;
所以如果(len%(len-next[len])==0)就表明该字符串前缀与后缀相等的数量大于等于1
这里我们就只需要一个函数就可以了
第三种情况:
还是两个串s,t;
求s中有多少个t;
例如:
这里只需要改下kmp算法,在找到一个后,不用立刻返回位置,而是一直找完。
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
。
kmp算法主要分两个部分实现:第一个部分,就是去求next数组的值;
第二个部分,就是两个字符串去匹配;
next数组是什么意思了,我个人认为就是当长度为j时,该字符串的前缀与后缀相等的长度;
例如:t[]="abcabc";
j=0,next[0]=-1;
j=1,字符串为"a",next[1]=0;
j=2,字符串为"ab",next[2]=0;
j=3,字符串为"abc",next[3]=0;
j=4,字符串为"abca",next[4]=1;
j=5,字符串为"abcab",next[5]=2;
最后当j==strlen(t),next[j]=3,表示该字符串前缀与后缀相等的最大长度;
实现代码:
<span style="font-size:18px;">void get_next(char t[],int next[]) { int len=strlen(t); int j=-1,i=0; next[i]=j; while(i<len) { if(j==-1||t[i]==t[j]) { i++; j++; next[i]=j; } else j=next[j]; } }</span>
最后就是匹配了,有几种不同的要求
第一:求在s串中出现的位置
<span style="font-size:18px;">int kmp(char *s,char *t,int pos) { int i=pos; int j=0; int len1=strlen(s),len2=strlen(t); while(i<len1&&j<len2) { if(j==-1||s[i]==t[j]) { i++; j++; } else { j=next[j]; } } if(j==len2) return i-len2; else return -1; }</span>
第二种:求周期
例如:ababab 周期为3;
因为我们已经说了:最后当j==strlen(t),next[j]=3,表示该字符串前缀与后缀相等的最大长度;
所以如果(len%(len-next[len])==0)就表明该字符串前缀与后缀相等的数量大于等于1
这里我们就只需要一个函数就可以了
<span style="font-size:18px;">#include <iostream> #include<cstdio> #include<cstring> #define maxn 1000000+10 using namespace std; char t[maxn]; int next[maxn]; void get_next(char t[],int next[]) { int len=strlen(t); int j=-1,i=0; next[i]=j; while(i<len) { if(j==-1||t[i]==t[j]) { i++; j++; next[i]=j; } else j=next[j]; } } int main() { while(~scanf("%s",t)) { if(strcmp(t,".")==0) break; get_next(t,next); int len=strlen(t); if(len%(len-next[len])==0) printf("%d\n",len/(len-next[len])); else printf("1\n"); } return 0; }</span>
第三种情况:
还是两个串s,t;
求s中有多少个t;
例如:
aaaaaa aa
3
这里只需要改下kmp算法,在找到一个后,不用立刻返回位置,而是一直找完。
<span style="font-size:18px;">int kmp(char *s,char *t,int pos,int *next) { int i=pos; int j=0,cnt=0; int len1=strlen(s),len2=strlen(t); while(i<=len1) { if(j==-1||s[i]==t[j]) { i++; j++; if(j==len2) { j=0; cnt++; } } else j=next[j]; } return cnt; }</span>暂时就是这么多了。
相关文章推荐
- constexpr-C++11
- c/c++ 使用比long long还大的类型
- C++总结之虚函数的作用(20160805)
- C++之路进阶codevs1269(匈牙利游戏)
- 八大排序算法Java、Python、C++实现 -- 快速排序
- 自己写的C++日志类log
- c++中printf("%5d%5d%5d%5d%5d", ++i, --i, i++, --i, -i--)的问题
- C++ Primer 第7章 知识点回顾
- 八大排序算法 Java、Python、C++实现 -- 冒泡排序
- C语言小游戏之猜数字,三子棋游戏
- Cpp环境【Code[VS]5226】物品选取
- 对typedef关键字的理解
- 复赛模拟试题 - 盛夏的果实 SPFA(队列优化)+二分答案法 重庆一中高2018级竞赛班第七次测试 2016.8.4 Problem 4
- ### 学习《C++ Primer》- 9
- Effective C++读书笔记---合理处理Operator =
- C++11 新特性:Lambda 表达式
- Effective C++读书笔记---为多态基类声明为virtual析构函数
- Vector初始化及用法
- Effective C++读书笔记---了解C++默默编写并调用哪些构造函数
- file 操作的一些记录