KMP算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KMP算法相关的知识,希望对你有一定的参考价值。
问题:在字符串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],则重复此步骤
算法如下:
//这个算法中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算法的主要内容,如果未能解决你的问题,请参考以下文章