//代码via:http://blog.csdn.net/v_JULY_v/article/details/6111565
//简单思路via:http://study.163.com/course/courseLearn.htm?courseId=468002#/learn/video?lessonId=1024414&courseId=468002
#include<iostream>
#include<string>
#include<vector>
using namespace std; int kmp_find(const string& target, const string& pattern)
{
const int target_length = target.size();
const int pattern_length = pattern.size();
int * overlay_value = new int[pattern_length];
overlay_value[] = -;
int index = ;
for (int i = ; i<pattern_length; ++i)
{
index = overlay_value[i - ];
while (index >= && pattern[index + ] != pattern[i])
{
index = overlay_value[index];
}
if (pattern[index + ] == pattern[i])
{
overlay_value[i] = index + ;
}
else
{
overlay_value[i] = -;
}
}
//match algorithm start
int pattern_index = ;
int target_index = ;
while (pattern_index<pattern_length&&target_index<target_length)
{
if (target[target_index] == pattern[pattern_index])
{
++target_index;
++pattern_index;
}
else if (pattern_index == )
{
++target_index;
}
else
{
pattern_index = overlay_value[pattern_index - ] + ;
}
}
if (pattern_index == pattern_length)
{
return target_index - pattern_index;
}
else
{
return -;
}
delete[] overlay_value;
} int main()
{
string source = "ann6bcdanacadsannannabnna";
string pattern = "n6bcdan";
cout << kmp_find(source, pattern) << endl;
return ;
}
相比BF算法(暴力匹配)KMP算法的时间复杂度有所提升,尤其是处理无重复匹配串。
但是我们除了目标串与匹配串还需引入一个数组int next[];存放每次失配位置对应的匹配串右移位数,下标从1开始。next[0]规定为-1(任一负整数
如何获得next[]数组是一个关键。
代码之前先谈谈思路
1)next[]只与匹配串有关
2)如果匹配串没有重复,那么一切好说,next[]按脚标顺序即可
3)匹配串有重复的情况,这就是我们要讨论的重点了,下一次从匹配串的哪一位开始与适配位置所在的目标串元素进行比较?
这个位置就是我们next[i]所对应的值
next[i] 匹配子串长-(失配位置前重复数+1)