KMP 各版本实现代码
2011-11-14 23:02
337 查看
/* * DA-Main-KMP.cpp * * 两种版本, 每个版本的 找一个子串 及 找所有子串 * * 教材版 : 《数据结构域算法》 高等教育出版社 张铭等著 2008版 * 算法导论版 :《算法导论》第二版 及 《数据结构域算法》2004版 * * Created on: 2011-11-14 */ #include <iostream> #include <cstring> using namespace std; char Pattern[200], Str[200]; int next[200]; //////////////////////////////////////////// //教材版 //////////////////////////////////////////// void preKMP(char *P){ //优化 int j, k; int len = strlen(P); next[0] = -1; j = 0, k = -1; while(j < len - 1){ while(k >= 0 && P[j] != P[k]){ k = next[k]; } k++, j++; //不注的话是优化版 // if(P[j] != P[k]) next[j] = k; // else // next[j] = next[k]; } } int KMP_1(char *T, char *P, int start){ int i, j; int tLen = strlen(T); int pLen = strlen(P); i = start, j = 0; while(i < tLen && j < pLen){ while(j >= 0 && T[i] != P[j]){ j = next[j]; } i++, j++; } if(j >= pLen) return i - pLen; return -1; } int KMP_2(char *T, char *P, int start){ int i, j; int tLen = strlen(T); int pLen = strlen(P); i = start, j = 0; while(i < tLen && j < pLen){ if(j == -1 || T[i] == P[j]) i++, j++; else j = next[j]; } if(j >= pLen) return i - pLen; return -1; } //找所有子串 void KMP_3(char *T, char *P, int start){ int i, j; int tLen = strlen(T); int pLen = strlen(P); i = start, j = 0; while(i < tLen){ while(j >= 0 && T[i] != P[j]){ j = next[j]; } if(j == pLen - 1){ cout << i - j << endl; j = next[j]; } else //注意加else!!!!!!!!!!!!!!!!!!!!!!!!!!! i++, j++; } } void KMP_4(char *T, char *P, int start){ int i, j; int tLen = strlen(T); int pLen = strlen(P); i = start, j = 0; while(i < tLen){ if(j == -1 || T[i] == P[j]){ if(j == pLen - 1){ cout << i - j << endl; j = next[j]; } else i++, j++; } else j = next[j]; } } //////////////////////////////////////// //算法导论版\04教材版 (注意 算法导论 中下标从1开始, 所以有所不同) //////////////////////////////////////// void preKMP_CLRS(char *P){ int j, k; int pLen = strlen(P); next[0] = 0; for(j=1; j<pLen; j++){ k = next[j-1]; while(k > 0 && P[j] != P[k]) k = next[k-1]; //下标从0开始,所以长度 = 下标 +1 if(P[j] == P[k]) k++; next[j] = k; } } int KMP_CLRS(char *T, char *P, int start){ int i, j; int tLen = strlen(T); int pLen = strlen(P); j = 0; for(i=start; i<tLen; i++){ while(j > 0 && T[i] != P[j]){ j = next[j-1]; } if(T[i] == P[j]) j++; if(j == pLen) return i - j + 1; } return -1; } //找所有子串 void KMP_CLRS_2(char *T, char *P, int start){ int i, j; int tLen = strlen(T); int pLen = strlen(P); j = 0; for(i=start; i<tLen; i++){ while(j > 0 && T[i] != P[j]){ j = next[j-1]; } if(T[i] == P[j]){ if(j == pLen - 1){ cout << i - j << endl; j = next[j]; j--; //注意:长度 = 下标 + 1 } j++; } } } void test(){ cin >> Str >> Pattern; preKMP(Pattern); cout << "next : " << endl; for(int i=0; i<strlen(Pattern); i++) cout << next[i] << ""; cout << endl << endl; cout << KMP_1(Str, Pattern, 0) << endl; cout << KMP_2(Str, Pattern, 0) << endl; cout << endl; KMP_3(Str, Pattern, 0); cout << endl; KMP_4(Str, Pattern, 0); cout << endl; ///////////////////////////////// preKMP_CLRS(Pattern); cout << "next_CLRS : " << endl; for(int i=0; i<strlen(Pattern); i++) cout << next[i] << ""; cout << endl << endl; cout << KMP_CLRS(Str, Pattern, 0) << endl; cout << endl; KMP_CLRS_2(Str, Pattern, 0); } int main(){ test(); return 0; }
相关文章推荐
- 百度云网盘 360云盘 金山快盘 等 + Git GUI 实现代码版本管理-个人篇
- 记录如何借助网盘搭建SVN服务器实现版本控制和代码同步
- KMP的原理和代码实现(详细注释|参考多个博客总结|可作为模板)
- LS代码实现点复选框即时弹出子表单(R6以上版本)
- Atitit.uml2 api 的编程代码实现设计uml开发 使用eclipse jar java 版本
- thinkphp3.2.3版本的数据库增删改查实现代码
- 【Ionic】Ionic实现iOS与Android端代码『热更新』与Android升级下载功能 ( v1.3.x版本 )
- VS2010搭建SVN,实现代码的版本控制----【SVN服务器搭建】
- struts2 案例代码实现及遇到的问题【struts2.5版本】
- Android5.0以上版本录屏实现代码(完整代码)
- google suggest 下拉菜单实现代码(asp.net版本)
- pycharm连接github实现代码版本控制
- Visual Studio 实现 编写一套.net代码,同时编译到 多个平台,多版本的操作笔记
- Atitit.uml2 api 的编程代码实现设计uml开发 使用eclipse jar java 版本
- “花生壳” + “VisualSVN” 巧妙实现远程代码版本控制
- 百度云网盘 360云盘 金山快盘 等 + Git GUI 实现代码版本管理-个人篇
- VS2010搭建SVN实现代码的版本控制VS2010插件安装
- asp.net(c#)程序版本升级更新的实现代码
- (ThreadLocal版本)Mybatis使用拦截器自动分页实现/使用反射替换sql代码分页
- Android使用ViewDragHelper实现QQ6.X最新版本侧滑界面效果实例代码