Kmp算法的两种写法
来源:互联网 发布:win10没有网络协议 编辑:程序博客网 时间:2024/06/05 05:04
总结:KMP算法的重点是求next数组。注意,该数组只和模式串有关系,和要匹配的串没有关系。
两种写法的基本思想是一致的。只是求next数组的方式不同,next数组所得的值也有所不同,代表的含义也不同。
原理不多说,网上讲的很多,这里只贴出完整的实现代码。
一般网上讲解的求next数组的都是针对方法二的。
第一种优化写法。
next[i]表示匹配串在i处如果匹配失败下次移到的位置.
const int N = 100;int next[N];int pattern_len, str_len;char pattern[N];char str[N];//求next数组的值. 即预处理void getNext1(){int i = 0, j = -1;next[0] = -1;while (i < pattern_len - 1){//cout << i << " " << j << endl;if (j == -1 || pattern[i] == pattern[j]){++i;++j;if (pattern[i] != pattern[j])next[i] = j;elsenext[i] = next[j];}elsej = next[j];}}int kmp1(){int i = 0, j = 0;str_len = strlen(str);while (i < str_len && j < pattern_len){if (j == -1 || str[i] == pattern[j]){++i;++j;}elsej = next[j];}if (j >= pattern_len)return i - pattern_len;elsereturn -1;}
第二种,经典写法.
next[i]表示 最远匹配到的位置。
以ABCDABD为例:-1 -1 -1 -1 0 1 -1
abcbabc : -1 -1 -1 -1 0 1 2
void getNext2(){next[0] = -1;int pre; //注,此处的i是从1开始的for (int i = 1; i < pattern_len; ++i){pre = next[i - 1];//向前回溯 prewhile (pre >= 0 && pattern[pre + 1] != pattern[i]){pre = next[pre];// cout << i << " index: " << pre << " back " << endl ;}// cout << "i:" <<i << " " << pre << endl;if (pattern[pre + 1] == pattern[i])next[i] = pre + 1;elsenext[i] = -1; //由于前面已经回溯,这里可直接赋值为-1}}int kmp2(){int p_index = 0, t_index = 0;while (p_index < pattern_len && t_index < str_len){if (str[t_index] == pattern[p_index]){++t_index;++p_index;}else if (p_index == 0)++t_index;elsep_index = next[p_index - 1] + 1;}if (p_index == pattern_len)return t_index - pattern_len;elsereturn -1;}
int main(){freopen("in.txt", "r", stdin);while(gets(str)){gets(pattern);pattern_len = strlen(pattern);//if(str[0] == '#') continue;getNext1();int ans = kmp1();cout << "next1: ";for(int i=0; i<pattern_len; i++) cout << next[i] << " ";cout << endl;cout << ans << endl;getNext2();cout << "next2: ";for(int i=0; i<pattern_len; i++) cout << next[i] << " ";cout << endl; ans = kmp2();cout << ans << endl;}}
测试数据:
/*
abadfabaabacd
abac
ababcbabcbaca
abcbabc
*/
next1: -1 0 -1 1 8next2: -1 -1 0 -1 8next1: -1 0 0 0 -1 0 0 2next2: -1 -1 -1 -1 0 1 2 2
- Kmp算法的两种写法
- KMP的两种写法
- 两种KMP算法
- Prim算法的两种写法
- KMP算法中的next数组的两种算法求解
- KMP两种写法以及AC自动机失配数组间的区别
- [算法] 两种快速排序的while写法
- KMP算法 NEXT数组的两种形式
- Dijkstra算法(两种写法)
- 状态机的两种写法
- 状态机的两种写法
- 状态机的两种写法
- 状态机的两种写法
- 对象的两种写法
- 状态机的两种写法
- 有限状态机的两种写法
- 状态机的两种写法
- 状态机的两种写法
- 消息系统架构设计
- IOS TableView 数据列表与设置页面(个人)
- Error: Connection activation failed: Device not managed by NetworkManager
- 开始我的博客之旅
- 开始学习Sencha Touch
- Kmp算法的两种写法
- 我是个宅男,天天就想着美女---Android app>>Girl Style看过来
- java实现MD5数据加密
- 多线程例子
- 游戏网络编程非常好的资料
- 逆波兰表达式学习日记(1)
- FreeMind 画的TCPIP四层OSI七层协议
- DWR配置
- jquery 实现原理七:DOM遍历-tranversing