字符串匹配-扩展KMP(Extend-KMP)
来源:互联网 发布:网络女作家 编辑:程序博客网 时间:2024/05/16 06:16
首先还是来看看问题:
给出一个长为N的字符串S,再给出一个长为M的字符串T
求S的所有后缀中和T的最长公共前缀
显然可以想到暴力的做法,枚举S所有的后缀,然后和T做匹配,时间复杂度为
显然,这个方法和之前的暴力一样,都处理了太多的重复操作,那么可以用类似KMP的方法来处理吗?
答案是肯定的,也就是Extend-KMP算法
可以先用类似KMP的想法,用
接着设p为答案伸得最远的后缀的下标,也就是
如果这两个串的公共前缀没有包括
接下来举个栗子:
字符串
那么
根据之前求出的,可以知道
根据之前的结果推导出
然后检查是否能够增加,发现
用类似这样的方法,同样可以直接推导出extend的结果,那么就得到了答案。
以下为代码:
void get_next() { int len = strlen(T); _next[0] = len; int a = 0; while(a < len - 1 && T[a] == T[a + 1]) { ++a; } _next[1] = a; a = 1; for(int k = 2; k < len; ++k) { int p = a + _next[a] - 1; int L = _next[k - a]; if(k - 1 + L >= p) { int j = (p - k + 1) > 0 ? (p - k + 1) : 0; while(k + j < len && T[k + j] == T[j]) { ++j; } _next[k] = j; a = k; } else { _next[k] = L; } }}void ExtendKMP() { int i = 0, j, po, lenS = strlen(S), lenT = strlen(T); get_next(); while(S[i] == T[i] && i < lenT && i < lenS) { i++; } ex[0] = i; po = 0; for(i = 1; i < lenS; i++) { if(_next[i - po] + i < ex[po] + po) { ex[i] = _next[i - po]; } else { j = ex[po] + po - i; if(j < 0) { j = 0; } while(i + j < lenS && j < lenT && S[j + i] == T[j]) { j++; } ex[i] = j; po = i; } }}
代码有点长……
最后来看看时间复杂度:
先看求
因为内部while每运行一次,j至少加1,最多执行M次,再加上外层循环的语句,时间复杂度为
求
但是相对于KMP来说,这个算法的常数比较差,所以实际运行时应该会慢一点,但对于不是线性时间求出答案的方法,是很快的。
- 字符串匹配-扩展KMP(Extend-KMP)
- 字符串匹配-扩展KMP
- 扩展KMP算法 Extend KMP
- CodeVS1404 字符串匹配(扩展kmp)
- KMP 字符串匹配算法
- kmp字符串匹配算法
- kmp字符串匹配算法
- KMP字符串匹配算法
- 字符串匹配算法-kmp
- KMP(字符串匹配)算法
- 字符串匹配 KMP
- KMP 字符串匹配算法
- 字符串匹配算法:KMP
- KMP算法 字符串匹配
- 字符串匹配 KMP 算法
- KMP字符串匹配(1)
- KMP字符串匹配(2)
- KMP字符串匹配(3)
- 在PyCharm中运行django 项目
- JAVAIO一次写入任意字符固定套路
- 登录安全性 一天内连续输入密码错误3次,第二天才能登录(过了当天凌晨24点),实现原理
- 欧拉函数PHI
- 用户登录记住密码功能(记住登陆状态),下次不需要重新登录,注意安全问题!实现原理
- 字符串匹配-扩展KMP(Extend-KMP)
- Java与云计算有什么关系呢
- 最大公约数和最小公倍数
- 邮箱找回密码功能
- PHP中的正则表达式
- Inkscape tutorial: Shapes
- MyBatis基础
- hdu1232 畅通工程--并查集
- hdu1879 继续畅通工程--prim