KMP算法笔记
来源:互联网 发布:丰田车导航软件 编辑:程序博客网 时间:2024/06/05 05:07
从开始了解学习KMP到现在已经第三遍了…………借着项目写RKR-GST算法也用到字符串模式匹配,顺便再把KMP弄清楚些。
模式串为“abaabcaba”:
next[j] = k 代表p[j] 之前的模式串子串中,有长度为k 的相同前缀和后缀。
next[j+1] 对于pattern的前j+1个序列字符:
- 若pattern[k] == pattern[j],则next[j + 1 ] = next [j] + 1 = k + 1;
- 若pattern[k ] ≠ pattern[j],如果此时pattern[ next[k] ] == pattern[j ],则next[ j + 1 ] = next[k] + 1,否则继续递归重复此过程。
#include <iostream>#include <cstring>using namespace std;int violentMatch(char *s, char *p){ int sLen = (int)strlen(s); int pLen = (int)strlen(p); int i = 0, j = 0; while (i < sLen && j < pLen) { if (s[i] == p[j]) { //①如果当前字符匹配成功(即S[i] == P[j]),则i++,j++ i++; j++; } else { //②如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0 i = i - j + 1; j = 0; } } //匹配成功,返回模式串p在文本串s中的位置,否则返回-1 if (j == pLen) return i - j; else return -1;}void initNext(char *p, int next[]){ int pLen = (int)strlen(p); next[0] = -1; int k = -1; int j = 0; while (j < pLen - 1) { //p[k]表示前缀,p[j]表示后缀 if (k == -1 || p[j] == p[k]) { ++j; ++k; next[j] = k; } else { k = next[k]; } }}void myInitNext(char *p, int next[]){ int pLen = (int)strlen(p); next[0] = -1; for (int j = 0, k = -1; j < pLen - 1; j++) { while (!(k == -1 || p[j] == p[k]))<span style="white-space:pre"></span>//“递归”向前查找 k = next[k]; next[j+1] = ++k; }}int kmpSearch(char *s, char *p, int next[]){ int i = 0, j = 0; int sLen = (int)strlen(s); int pLen = (int)strlen(p); while (i < sLen && j < pLen) { //①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++ if (j == -1 || s[i] == p[j]) { i++; j++; } else { //②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j] //next[j]即为j所对应的next值 j = next[j]; } } if (j == pLen) return i - j; else return -1;}int myKMPSearch(char *s, char *p, int next[]){ int sLen = (int)strlen(s); int pLen = (int)strlen(p); for (int i = 0, j = 0; i < sLen; i++, j++) { if (j == pLen) return i - j; else if (j == -1) j = 0; if (s[i] != p[j]) j = next[j]; } return -1;}int myKMPSearch1(char *s, char *p, int next[]){ int sLen = (int)strlen(s); int pLen = (int)strlen(p); for (int i = 0, j = 0; i < sLen; i++, j++) { if (j == pLen) return i - j; if (s[i] != p[j]) j = max(next[j], 0); } return -1;}int myKMPSearch2(char *s, char *p, int next[]){ next[0] = 0; int sLen = (int)strlen(s); int pLen = (int)strlen(p); for (int i = 0, j = 0; i < sLen; i++, j++) { if (j == pLen) return i - j; if (s[i] != p[j]) j = next[j]; } return -1;}int main(int argc, const char * argv[]){ char s[] = "BBC ABCDAB ABCDABCDABDABABE"; char p[] = "ABCDABC"; int matchPos; int next[100]; initNext(p, next); for (int i = 0; i < strlen(p); i++) cout << next[i] << " "; cout << endl; matchPos = kmpSearch(s, p, next); cout << matchPos << endl; myInitNext(p, next); for (int i = 0; i < strlen(p); i++) cout << next[i] << " "; cout << endl; matchPos = myKMPSearch(s, p, next); cout << matchPos << endl; cout << "myKMPSearch1:" << endl; matchPos = myKMPSearch1(s, p, next); cout << matchPos << endl; cout << "myKMPSearch2:" << endl; matchPos = myKMPSearch2(s, p, next); cout << matchPos << endl; cout << "violentMatch:" << endl; matchPos = violentMatch(s, p); cout << matchPos << endl; return 0;}
详细KMP算法参考:http://blog.csdn.net/v_july_v/article/details/7041827
0 0
- KMP算法学习笔记
- KMP算法笔记
- KMP算法笔记
- KMP算法 笔记
- KMP算法笔记
- 学习笔记-KMP算法
- 数据结构笔记-KMP算法
- KMP算法 学习笔记
- Kmp算法学习笔记
- KMP算法笔记
- KMP算法学习笔记
- KMP算法笔记
- KMP算法学习笔记
- KMP算法学习笔记
- KMP算法学习笔记
- KMP算法学习笔记
- 学习笔记-KMP算法
- KMP算法笔记
- POJ2001_Shortest Prefixes(字典树)
- 【大数模板+十进制+for_loop】Multiply Strings
- apn生成信鸽服务端推送需要使用的pem
- java基础知识之内部类
- 目前最完整的Linux常用基础命令
- KMP算法笔记
- fedora xface 更改系统语言
- 解决Python中Pyramid 1.5a2+框架的Chameleon、Mako模板引用故障
- JQuery获取$(this)子节点对象的方法
- 黑马程序员 java学习笔记——IO流2
- Vi编辑器的使用方法
- [leetcode] Search Insert Position
- 算法学习 - 插入排序,希尔排序
- Spring中的applicationContext.xml与SpringMVC的xxx-servlet.xml的区别