# 【算法与数据结构】KMP算法

Kmp由于其超低的时间复杂度O(m+n)，因而被应用到广泛的应用到各种编辑器上。作为基础算法，网上有太多的人孜孜不倦的写教程，所以具体思想也就不再赘述。

KMP算法详解

Kmp算法排除思想外，很值得说的就是由于其不回溯的特性，其适用于大型匹配。

#include<iostream>
#include<string>

#define DEBUG

#ifdef DEBUG

#include<vector>

#endif // DEBUG

class Kmp {

public:

Kmp(const std::string& str)
:substr{ str }, next{ new int[str.length()+1]{} } {

getnext(substr,next);
}

~Kmp(){

if (next != nullptr) {
delete[] next;
}
}

int capture(std::string str) {

#ifdef DEBUG
std::vector<char> all;;
#endif // DEBUG

const auto subLength = substr.length();
const auto strLength = str.length();
size_t i = 0, j = 0;
while (j == -1 || i < strLength  && j < subLength) {

if ( str[i] == substr[j] ) {

#ifdef DEBUG
all.push_back(str[i]);
letterVector.push_back(str[i]);
#endif // DEBUG

i += 1;
j += 1;
}
else {

j = next[j];

if (j == -1) { i++; j++;}

#ifdef DEBUG

all.push_back(str[i]);
auto beDele = letterVector.begin() + letterVector.size() - j;
letterVector.erase(letterVector.begin(), beDele);
#endif // DEBUG

}
}

if ( j < subLength) {

return i - subLength;
}

#ifdef DEBUG
std::cout << all.size() << std::endl;
std::cout << "The last matching sequences ：" << std::endl;
for (auto letter : letterVector) {

std::cout << letter << "  ";
}
#endif // DEBUG

return 0;
}

private:

void getnext(const std::string& subStr, int  next[]) {

next[0] = -1;
int j = -1;
size_t i = 0;
while (i < subStr.length()){

if (j == -1 || subStr[i] == subStr[j]) {

/*j++;
i++;
next[i] = j;*/

if (subStr[++i] == subStr[++j]) {

next[i] = next[j];
}
else {

next[i] = j;
}
}
else{

j = next[j];
}
}

#ifdef DEBUG

std::cout << "next sequnences:";
for (auto i = 0; i < substr.length(); i++) {

std::cout << next[i] <<" ";
}
std::cout << std::endl;
#endif // DEBUG

}

private:

std::string substr;
int *next;

#ifdef DEBUG

std::vector<char> letterVector;

#endif // DEBUG
};

int main() {
auto sequece = "ABCDABABCDABXBABCDABABCDABB";
Kmp check{ "ABABAAB" };
std::cout<<check.capture(sequece);
return 0;
}