码迷,mamicode.com
首页 > 编程语言 > 详细

KMP算法

时间:2017-11-13 00:09:15      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:new   ref   相同   http   步骤   i+1   构造   问题   logs   

问题:在字符串S中找到与字符串M相匹配的子串

步骤:

1:构造字符串M的next数组。

目的:匹配时,当M[i]与S[j]不匹配了,确定能将M向后移动的最多位数。

解释:next数组中保存的是在M[i]之前,与M起始串相匹配的最大子串。换个角度,保证若将M串向后移动少于i-next[i]+1位,在S[j](M[i])之前S与M不可能全部匹配。因为若少移动了几位仍然可以匹配到S[j]甚至S[j]之后的位,则从M[0]到S[j]之间的M的子串与M[i-1]到M[i-j-1]相同,那么这是M[0]到M[i-1]前缀与后缀的最大公共子串,且这个长度大于next[i]的值,与next数组的定义矛盾,故不可能。

构造方法:若next[i]=k,则next[i+1]有以下两种情况:

1).若M[i] = M[k],则next[i+1] = k+1;

2).若M[i] != M[k],则设next[k]=j,若M[j] = M[i],则next[i+1] = j+1 = next[next[i]]+1;若M[j] != M[i],则重复此步骤

原理见史上最浅显易懂的KMP算法讲解

算法如下:

//这个算法中next数组下标从1开始对应字符串下标0
int *compute_next(const string& pattern) { const int pattern_length = pattern.size(); int *next_function = new int[pattern_length]; int index; next_function[0] = -1; for(int i=1;i<pattern_length;++i) { index = next_function[i-1]; //store previous fail position k to index; while(index>=0 && pattern[i]!=pattern[index+1]) { index = next_function[index]; } if(pattern[i]==pattern[index+1]) { next_function[i] = index + 1; } else { next_function[i] = -1; } } return next_function;
 } 

 

2:从左到右匹配S与M,当M[x]不匹配时,将M向后移动x-next[x+1]个字符即可

KMP算法

标签:new   ref   相同   http   步骤   i+1   构造   问题   logs   

原文地址:http://www.cnblogs.com/ilmare-notebook/p/7807050.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!