【啊哈,算法】之八、串和kmp算法
来源:互联网 发布:python 培训 郑州 编辑:程序博客网 时间:2024/06/03 17:31
字符串大家应该不陌生了!
个人代码积累:
先来看看串的结构定义:
#include<iostream>using namespace std;typedef char Type;#define MAXSIZE 100typedef struct String{Type data[MAXSIZE];int length;}String;
串有许多操作,如:初始化,创建串,清空串,插入,复制,比较,链接,寻找字串,寻找串的位置等:
void StrInsert(String *S, int pos, String T){if(S->length >= MAXSIZE){cout << "插入失败" << endl;return ;}int i = S->length - 1;int n = T.length;for(; i >= pos; --i){S->data[i+n] = S->data[i];}i++;for(int j = 0; j < n; j++){S->data[i++] = T.data[j];}S->length = S->length + T.length;}void InitString(String *S){for(int i = 0; i < MAXSIZE; ++i)S->data[i] = 0;S->length = 0;}void CreateString(String *S){Type e;int n;cout << "请输入元素个数:";cin >> n;S->length = n;int i = 0;while(n--){cout << "请输入数据:";cin >> e;S->data[i++] = e;}}void StrCopy(String *S, String T){for(int i = 0; i < T.length; i++){S->data[i + S->length] = T.data[i];}S->length = S->length + T.length;}void ClearString(String *S){InitString(S);}bool StringEmpty(String S){if(S.length == 0)return true;elsereturn false;}int StrLength(String S){return S.length;}int StrCompare(String S, String T){if(S.length > T.length)return 1;if(S.length < T.length)return -1;for(int i = 0; i < S.length; ++i){if(S.data[i] > T.data[i])return 1;if(S.data[i] < T.data[i])return -1;}return 0;}void StrCat(String *S, String S1, String S2){S->length = S1.length + S2.length;StrInsert(S, 0, S1);StrInsert(S, S1.length, S2);}void SubString(String *Sub, String S, int pos, int len){int j = 0;for(int i = pos; i < pos+len; ++i){Sub->data[j++] = S.data[i];}Sub->length = len;}int Index(String S, String T, int pos){if(S.length == 0 || T.length == 0){return -1;}String Sub;InitString(&Sub);if(pos > 0){int s = S.length;int t = T.length;int i = pos;if(s < t)return -1;while ( i <= s - t + 1){SubString(&Sub, S, i, t);if(StrCompare(Sub, T) != 0)++i;elsereturn i+1;}}return 0;}int Index2(String S, String T, int pos){int s = S.length;int t = T.length;if(s < t || s < 0 || t < 0)return -1;int i = pos;int j = 0;while (i < s && j < t){if(S.data[i] == T.data[j]){++i;++j;}else{i = i - j + 1;j = 0;}}if(j >= t)return i - t + 1;elsereturn 0;}void StrDelete(String *S, int pos, int len){if(S->length < len){cout << "error" << endl;return ;}for(int i = pos - 1; i < S->length - len; ++i){S->data[i] = S->data[i + len];}S->length -= len;}
下面来看KMP算法:
KMP算法是通过分析子串,预先计算每个位置发生不匹配的时候,所需GOTO的下一个比较位置,整理出来一个next数组,然后在上面的算法中使用。
他的时间复杂 度是O(m+n) 相比朴素比较算法O((n-m+1)*m)来说当然很快。
本算法你需要知道如何构建next数组。 也就是你跟主串比较,子串中有相似项,其比较过后就不必再比较了。
next是什么?
next数组是你的串中各个位置 其当前字符之前的串的前后缀的相似度。(此时相似度我们看为j)
如:abcabx; x之前,前缀ab与后缀ab相同,此时他们的取值也就是3。 为何? 看图:
得出公式:
下面我们来看几个例子:
看到这里,我还想说的就是此时的next是有缺陷的,比如我们的主串是 S="aaaabcde" 子串是T="aaaaax“ 那么他的next数组是 012345, 开始 i=5,j=5 我们发现b和a不等, 此时j=next【5】 = 4, 此时b和第四个位置的a也不想等
此时 j=next4 = 3. 直到j=next1 = 0为止,此时i++ j++得到i=6,j=1.
大家有木有发现此时2345步骤是多余的呢。 由于T的第二三四五位置的字符都与首位的a相等,那么可以用首位next1的值去取代与它相等的字符后续next的值,我们需要改进:
下面看几个例子:
下面看代码:
void get_nextval(String T, int *next){/*//待改进int t = T.length;int i = 1;int j = 0;next[1] = 0;while(i < t){if(j == 0 || T.data[i] == T.data[j]){++i;++j;next[i] = j;}elsej = next[j];}*///改进算法int t = T.length;int i = 1;int j = 0;next[1] = 0;while ( i < t){if(j == 0 || T.data[i] == T.data[j]){++i;++j;if(T.data[i] != T.data[j])next[i] = j;elsenext[i] = next[j];}elsej = next[j]; //若字符不同则回 朔}}int Index_KMP(String S, String T, int pos){int i = pos - 1;int s = S.length, t = T.length;int j = 1;int nexts[MAXSIZE];get_nextval(T, nexts);while ( i <= s && j <= t){if(j == 0 || S.data[i] == T.data[j-1]){++i;++j;}else{j = nexts[j];}}if( j > t )return i - t + 1;elsereturn 0;}
2013.8.2
jofranks 于南昌
- 【啊哈,算法】之八、串和kmp算法
- 啊哈算法 之 队列
- 啊哈,算法之二分思想
- 啊哈算法 之 冒泡排序
- 啊哈算法 之 快速排序
- 《啊哈!算法》
- 《啊哈!算法》
- 啊哈!算法
- 啊哈算法搜索应用之宝岛探险(BFS和DFS)
- 串和KMP算法
- 【啊哈!算法】算法3:八一八“快速排序”
- 串模式匹配之BF算法和KMP算法
- 《数据结构和算法》之KMP算法
- (八)实现了串比较里的BF算法和KMP算法
- 算法之KMP算法
- 啊哈!算法-------算法类书籍
- 啊哈,算法 之原语的力量
- 【啊哈!算法】之二、插入排序
- hdu 1172
- Motion JPEG格式流媒体服务器(转)
- jqGrid设置remote和url访问的方式
- 找出数组中出现奇数次的元素<异或的应用>
- Kendo UI PanelBar For MVC 生成下拉菜单
- 【啊哈,算法】之八、串和kmp算法
- linux打包压缩命令汇总
- 区间DP
- HDU 1062
- uva 537
- Struts2的工作原理1
- Centos 6.X的NFS配置
- 学java,选择传智播客java培训的8大理由
- lsof常见用法--统计打开文件数