KMP算法的思想
来源:互联网 发布:c语言最大水仙花数程序 编辑:程序博客网 时间:2024/05/13 00:39
在计算机中,字符串的搜索很重要。昨天突然想起KMP算法,找了书复习了一下。把具体的思想写下来和大家共享。为什么会出现KMP算法,因为一般的字符串匹配可能会比较浪费时间。现在讲的是速率。例如:主串是:ababcabcacbab,有个子串:abcac,一般的匹配是一个一个比较,如果不等,子串从头开始,而主串则跳到开始比较的第一个字符的下一个字符。第一次主串的ab和子串的ab相等,但到第三个就不等了。这时主串跳到开始比较的下个字符,则是a后的从b开始。而子串从头开始则从a开始。这样比较浪费时间。
KMP算法的作法:不像一般匹配,当我们失配时,主串保持失配时的位置不变,而子串跳到前面一个适合的位置K(不用跳到第一个)。这时,问题就在这样确定新位置K了。
所以我们可以把子串先做预处理。KMP依靠两条重要的理论:s表示主串。p表示子串。‘i’表示失配时主串的位置,‘j’表示失配时子串的位置,例如第一次‘j’为3。k表示子串失配后应该开始的位置,而不是每次都从开头重新开始。 公式(‘括号()里的字母表示下标,例如P(j-k+1):下标是j-k+1’) (可以参考严蔚敏数据结构P81)
(1)P(j-k+1)P(j-k+2).....P(j-1) = S(i-k+1)S(j-k+2)....S(i-1) //已经匹配可得出的条件i , j是主、子串失配的位置
(2) P(1)P(2)...P(k-1) = S(i-k+1)S(i-k+2)...S(i-1) //这条是我们要求在k位置开始匹配要满足的条件
由(1)(2)可得==> P(j-k+1)P(j-k+2).....P(j-1) = P(1)P(2)...P(k-1) //很关键,我们可以看出求下个重新匹配的位置 k 原来是和“主串”没关系的。这个很重要!
KMP算法中核心就是把“子串”预处理下,就是令next【j】= k; 就是说我们用个next数组来装子串每一个失配 “j” 要跳到新位置 “k”的数组,前面说过,其实子串失配后应该从新开始的位置和主串没联系的。只要子串不变,换个别主串next【j】还是一样。
(1) 当 j =1时。也就是第一个就失配了。则 next[ j ] = 0;
(2)当 满足P(j-k+1)P(j-k+2).....P(j-1) = P(1)P(2)...P(k-1),求最大的K 作为 next【 j 】 = K;
(3)其他情况 next[ j ] = 1;
具体怎么求这个有点难。可以参考书籍,书上讲了比较多。下面我只是写出来。理解还要花时间去看详细资料。大家主要要知道这种预处理的思想可以提高效率就OK。
/////求next【】的函数
void Get_next(char T[], int next[]) // 这里T[]是子串,而且T[ 0 ] 是放着字符串的长度
{
int i =1, j = 0;
next[1] = 0;
while (i < T[0]) ///// T[ 0 ] 是放着字符串的长度
{
if (j == 0 || T[i] == T[j])
{ ++i; ++j;
next[i] = j;
} // end if
else
{ j = next[j]; }
} // end while
} // end Get_next()
///// “kmp”的函数。返回的是子串在主串匹配到的位置
int Index_KMP(char S[], char T[], int next[]) ///S是主串,T是子串
{
int i = 1, j = 1;
while (i <= S[0] && j <= T[0]) /// S[0 ]、T[ 0 ]分别是主串和子串的长度
{
if (j == 0 || S[i] == T[j])
{ ++i;
++j;
}
else { j = next[ j ]; }
} /// end while
if (j > T[0]) //如果j > T[0] 说明在S找得到子串T
{
return i - T[0]; //这时 i 是主串和子串匹配成功最后的的位置,还要减去子串的长度,才是子串在主串 匹配成功的起始位置
}
else return 0;
}
我这里讲的不是很详细。呵呵,只是把主要的思想说出来,理解可能还要花时间。我自己也想了很久。希望大家有所收获~
- KMP算法的思想
- KMP算法 的思想
- 基于dfa的kmp算法思想
- 完全掌握KMP算法思想
- 【总结】理解KMP算法思想
- kmp算法的思想及其简单应用(java版)
- 基于有限自动机的KMP算法构造思想
- kmp算法中next[]数组求法的基本思想
- 完全掌握KMP算法思想 (文本比较)
- KMP算法基本思想与实现
- 深入理解KMP算法核心思想
- 字符串精确匹配KMP算法思想演变
- KMP算法代码实现和优化(不太能理解具体的过程和该算法思想)
- 数据结构KMP算法中next函数的求解思想及其解释
- KMP思想
- KMP算法(2)-KMP算法的基础
- KMP算法的实现
- KMP算法的学习心得
- Valgrind 与 Linux 程序的内存问题
- 初学JavaScript 之 一个简单的JavaScript+css实现的菜单
- _variant_t的类型解说以及如何转换成其它类型
- Unix/Linux常用命令—文件的复制、删除和移动
- 表示层——业务逻辑层——数据访问层
- KMP算法的思想
- LVM Snapshot
- Double Checked Locking 模式
- 自己动手制作控制台定位函数
- Using the High-Level Input and Output Functions
- UBOOT 移植操作(转1)
- 背包问题 2
- uboot移植 之 2
- 将指定文件夹下结构相同的ACCESS文件内指定的表批量导入到SQL数据库中指定的表