月球美容计划之那些天我们学过的KMP
来源:互联网 发布:刘梦溪 知乎 编辑:程序博客网 时间:2024/05/01 14:08
问题描述
给两个字符串A,B,如A=“aaaaaaaaaaaaaaaaaaab”,
B = “aaaaaaaab”,现在要求B是否是A的字串。
普通方法(O(nm)),对两个字符串进行双重枚举进行匹配知道找到A字符串中的B字符串。
for(i = 0;i < n;i++){int tf = 0;for (k = 0;k < m;k++){if (A[i] != B[k]){tf = 0;break;}}if (tf)break;}
KMP小忆
KMP算法是通过分析模式字符串,预先计算每个位置发生不匹配的时候,所需跳转到的下一个比较位置,整理出来一个next数组,然后在上面的算法中使用。
其达到的最终效果是,避免记录字符串A的指针i回溯,从而节省一个循环,也就是把O(mn),降为O(m)。
因此,也就可以说,KMP就是对O(nm)算法的改良,因此,其改良的地方,就是其关键。也就是说next就是KMP的精华所在。
犹抱琵琶的next函数
寒假时总结的模板
void kmp (char *T,int next[]){ int j = 0,k = -1; next[0] = -1; while (T[j] != '\0') { if (k == -1 || T[j] == T[k]) { j++; k++; next[j] = k; }else k = next[k]; //相当于在求next的时候利用已求出的next }}
这个是非改进版的求next的函数。其next数组记录的数据x代表这个元素的位置,代表与整个字符串T的前x个字符相同。
不能小看next
next的使用不仅仅是其储存的内容的或用上,甚至不能小瞧在求next数组的时候其产的中间值。
记得有一个题,就是让求字符串中循环节的长度,记得以前做类似的题目的时候是用的双重枚举,如果用KMP的话,也是可以省掉的一层循环。
做这题求next的代码如下:
int fnext (char *T,int next[]){ int j = 0,k = -1; next[0] = -1; while (T[j] != '\0') { if (k == -1 || T[j] == T[k]) { j++; k++; next[j] = k; } else k = next[k]; } if (k == 0) return -1; return j - k;}
其中j指针指的是主字符串(不回溯的指针),k字符串指的是辅字符串(可以回溯),当next数组构建完成的一瞬间,想象一下j和k的样子,现在j指向了主字符串的最末尾,而k不一定指向哪,但可以肯定的是,如果T[j] != T[k],k一定不等于0,否则,k指向的位置x,一定会让字符串后x位与前x位相等。
也就是说,如果存在循环节,其循环节的长度就是j - k。
KMP带来的反思
KMP使用一个next数组让一种O(nm)的算法变为了O(n),有点用空间换时间的味道,像这种用空间换时间还有什么可以举一反三的吗?
KMP是利用空间,避免了在双重枚举的时候,一个指针的反复回溯,减少了一层循环。
那么,在做模拟题,尤其涉及到枚举的模拟题的时候,是不是在时间吃紧的情况下可以考虑通过存储某些东西,来去掉一层循环呢?
- 月球美容计划之那些天我们学过的KMP
- 月球美容计划之图的储存结构汇总
- 月球美容计划之二分哈希
- 月球美容计划之并查集
- 月球美容计划之最短路
- 月球美容计划之维尼的背包(基础篇)
- 月球美容计划之最小生成树(MST)
- 那些年我们学过的HTML
- 那些年我们学过的数据结构
- 那些年我们学过的算法
- 那些年,我们一起学过的汇编----之伪指令
- 那些年,我们一起学过的汇编----之程序返回操作系统
- 那些年,我们一起学过的汇编----之跳转指令
- 那些年,我们一起学过的汇编----之顺序、分支与循环程序设计
- 那些年,我们没有一起学过的英语。
- 那些年,我们一起学过的linux
- 那些年,我们一起学过的编程语言
- 那些年,我们一起学过的R语言
- Android中的序列化
- 电子信息工程专业的学生在校期间应该考哪些必要的资格证书?
- android中操作图片
- CF:Garland
- 约瑟夫环的实现
- 月球美容计划之那些天我们学过的KMP
- 网站收藏
- ubuntu中 codeblocks 下opengl的配置
- 黑马程序员------第2天笔记
- 数字证书验证过程
- Spring: DispacherServlet和ContextLoaderListener中的WebApplicationContext的关系
- Lucene排序
- crontab的应用
- 黑马程序员_指针数组