kmp算法
kmp 一种改进的字符串匹配算法
利用已知6位字符 “ABCDAB”,不要把 “搜索位置” 移回已经比较过的位置,继续把它往后移,这样提高效率
可以针对搜索词,算出一张 《部分匹配表》
查表可知,最后一个匹配字符B对应的 “部分匹配值”为 2,因此按照公式(移动位数 = 已匹配的字符数 - 对应部分的匹配值) 算出向后移动的位数 6-2 =4. 将搜索词往后移动 4位,变成:
因为空格与C 不匹配, 搜索词还要继续往后移。 这时 已匹配的字符数为2个(“AB”),对应的 “部分匹配值” 为0。所以,移动位数 = (2-0 = 2) ,于是 将搜索词 往后移动2位,变成:
空格与A 不匹配,继续后移一位。
逐位比较,直到发现C与D不匹配,于是,移动位数 = (6-2 = 4)位,变成:
发现完全匹配,搜索完成,是不是感觉很神奇呢? 匹配表怎么这么神了?怎么计算出来的?接着往下看!。
计算《部分匹配表》:
概念:
1.前缀: 除去字符串最后一个字符以外,一个字符串的全部头部组合
2.后缀:出去字符串第一个字符以外,一个字符串的全部尾部组合
例如: ABCD
前缀组合: A 、AB、 ABC
后缀组合: B 、BC、BCD
部分匹配表就是 “前缀” 和 “后缀” 的最长的 共有元素的长度,以 ABCDABD 为例:
A的长度 = 0;
AB的长度 = 0;
ABC的长度 = 0;
ABCD的长度 = 0;
ABCDA的长度 = 1;
ABCDAB的长度 = 2;
ABCDABD的长度 = 0;
推出此表:
例题:
在字符串中 KMP,求解字符串P的next函数值,字符串为”abaabaca“,则next 函数值为:?
j | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
字符串 | a | b | a | a | b | a | c | a |
next[J] | 第一步 0 | 第三步 1 | 第三步 1 | 第四步 2 |
解题步骤:
第一步. j = 1 时,next[0] = 0;
第二步. j = 2 时, k 的取值 为 (1,j) 的开区间, 所以整数 是不存在的,那就是第三种情况,next[2] = 1;
第三步. j = 3时, k的取值为 (1,3)的开区间,k从最大的开始取值,然后带入含p的式子中验证等式是否成立,不成立k取第二大的值,现在k = 2,将k 导入p的式子中得到: p1 = p2 , a = b 不成立,舍去,k再取值就超出范围了,所以next[3] 不属于第二种情况,那就是第三种情况,即next[3] = 1。
第四步:j= 4时,k的取值为 (1,4)的开区间,先取 k = 3, 将k导入p的式子中得到 p1 p2 = p2 p3 不成立。 再取 k = 2, 得到 p1 = p3 , a = a,成立,所以next[4] = 2
以此内推.......后面留给你们填了哈!