您的位置:首页 > 编程语言 > C语言/C++

KMP算法详解C++实现

2018-03-07 11:40 537 查看
KMP算法是判断两个字符串str1中是否包含与str2相同的子串。

next数组概念

KMP算法最关键的就是next数组。next数组就是针对str2串中每个字符前的子串中存在的前缀与后缀匹配的最长长度。假设str2为“abababca”。

j=0,字符str2[j]=a,a前没有字符串,默认为next[0]=-1;

j=1,字符str2[j]=b,b前子串为“a”,前后缀不存在,默认为next[1]=0;

j=2,字符str2[j]=a,a前子串为“ab”,前后缀不存在相等,则next[2]=0;

j=3,字符str2[j]=b,b前子串为“aba”,前后缀最大相等为a,则next[3]=1;

以此类推next[9]=[-1,0,0,1,2,3,4,0]

KMP匹配过程



next求法



通俗易懂的话来说就是你要求解当前位的next值,则看前一位与前一位next所在位字符是否相等,相等则当前位的next等于前一位next+1,如果不等就找前一位next的next与前一位比较,如果相等,当前位的next等于那个与前一位字符相等的字符所在位置+1,如果还是不相等,则以此类推,直到出现比较位为next[]=-1,那当前位的next就等于-1。

#include<iostream>
#include<thread>
#include<string>
#include<vector>
using std::cout;
using std::endl;

void getNext(int *next,const std::string &str) {
int i = 0;
next[0] = -1;
int k = -1;
while (i < (str.length() )) {
if (k == -1 || str[i] == str[k]) {
++i;
++k;
next[i] = k;
}
else {
k = next[k];
}
}
}

bool subString(const std::string &str1, const std::string &str2, std::vector<int> &position) {
int *next = new int[str2.length()+1];
getNext(next, str2);
int i = 0; // str1
int j = 0;//  str2
while (i<str1.length()){
if (j == -1 || str1[i] == str2[j]) {
++i;
++j;
if (j >= str2.length()) {
position.push_back(i - str2.length());
j = next[j];
}
}
else{
j = next[j];
}
}
delete[] next;
if (position.empty()) {
return false;
}
else{
return true;
}
}

int main() {
std::string str1 = "abababbbab";
std::<
aeaa
span class="hljs-built_in">string str2 = "aba";
std::vector<int> position;

subString(str1, str2, position);
for (auto it = position.begin(); it != position.end(); ++it) {
cout << (*it) << endl;
}

while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}

return 0;
}


其中很多参考杨守乐文章:http://mp.weixin.qq.com/s/2o2KLILAaFDf-aMDoLnbsA
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: