KMP的理解
来源:互联网 发布:西门子plc数据用于联网 编辑:程序博客网 时间:2024/05/19 18:42
KMP算法对串进行预处理,根据子串得出数组next,
不同与brute-force算法的是,当某位匹配失败时
1,主串不再回头进行匹配,仍从匹配失败的一位继续匹配,即 S[i] 与 T[j] 匹配失败时,i 不变化。(brute-force算法中 i = i - j)
2,子串不再回到首位进行匹配,而从 j = next[j] 进行下一次匹配。(brute-force中 j = 0)
下面,我们来分析一下next数组
int getNext(string target, int next[]){int n = target.size();int i = 0, j = 1;next[0] = -1;while (i < n){if (j == -1 || target[j] == target[i]){++j;++i; next[i] = j;}elsej = next[j];}}
next数组的意义在于: 子串 target[next[j]] 与 target[j] 拥有共同的前缀,这个前缀的长度不限定,只判断是否有共同前缀。
下面用 Kp 表示 子串 target[p] 的前缀(不包括target[p])
当 target[j] 等于 target[i] 时, K(j+1) = K(i+1),因此 next[i+1] = j + 1,
当target[j] 不等于 target[i] 时,默认 K(j -1) = K(i - 1),则 j 回溯 到 next[j] , next[j] 与 j 有相同 前缀, 因此与 i 也有相同 前缀,再次比较 target[next[j]] 于 target[i]
当 j 不断回溯,直到j = 0 时 target[j] 与target[i] 仍然匹配失败,则j = -1 此时 K(j + 1) 为0,可看作target[i+1] 于 target[j+1]有0个相同前缀, K(i+1) = K(j+1) = 0,则next[i+1] = j+1 = 0。
如图, 当 j = 3,abab 与 ab 有 共同前缀 ‘a’ (不包括target[j]) 共同前缀数为1,next[3] = 1
当 j = 4, ababb 与 abb 有共同前缀 ‘ab’ 因此 next[4] = 2
下面是利用 next 数组 进行字符串匹配
int strStr(string source, string target){const int sLen = source.size();const int tLen = target.size();int next[tLen];getNext(target, next);int i = 0, j = 0;while (i < sLen && j < tLen){if (source[i] == target[j]){++i;++j;}elsej = next[j];if (j == tLen) //match successreturn i - j;}return -1; // match fail}
以上是KMP匹配算法,正如前文所说
当 S[i] 与 T[j] 匹配失败时,j = next[j] ,即在子串中寻找一个 与 T[j] 有相同前缀 的 T[next[j]],则它与 S[i] 也有相同前缀(可能是0个),因此 i 匹配失败时不需要进行偏移,
next数组的优化:
int getNext(string target, int next[]){int n = target.size();int i = 0, j = 1;next[0] = -1;while (i < n){if (j == -1 || target[j] == target[i]){ ++j; ++i; if (target[j] == target[i]) next[i] = next[j]; else next[i] = j; } elsej = next[j]; }}
改进部分 在于 增加判断 target[j+1] 和 target[i+1]
当 target[i + 1] == target[j + 1] && K(i + 1) == K(j + 1) 的时候
如果 主串与子串的 target[i+1] 匹配失败,则主串与target[j + 1] 一定也不同,没必要进行比较,
则 子串 的下一个匹配的位置 向前回溯,直到与 target[i+1] 有相同的前缀,并且不等于target[i+1]
- KMP算法的理解
- KMP的理解
- KMP算法的理解
- kmp的简单理解
- 【算法】KMP的理解
- KMP的理解
- KMP算法的理解
- KMP算法的理解
- 自己理解的KMP
- 关于KMP的理解
- KMP算法的理解
- KMP的理解
- 关于KMP的理解
- KMP算法的理解
- [KMP]个人对于KMP算法的理解
- 有关KMP的一点点理解
- KMP算法的详细理解
- KMP算法的个人理解
- SharedPreferences 保存值
- java事务处理全解析(一)
- 第四届蓝桥杯B组第三题快速排序
- VC6.0中清除程序中所有的断点?
- C++根据前序和中序重建二叉树
- KMP的理解
- android菜鸟练手小项目之自定义日历,涵盖LitePal数据库,极光推送(一)
- 设计模式拾荒之命令模式( Command Pattern )
- 表格选择框----全选的动态勾选
- Java Switch()可以用的类型
- 57. Insert Interval
- Codeforces 3C Tic-tac-toe
- pom文件解析
- java RandomAccessFile随机读写流