语言:C++
思想:1、使待匹配串每次获得最大的偏移量
2、为了实现1,先得到一个对于待匹配串第一位的状态数组,表示下标[i]实现当前串向后滑动时的状态位置next[i]
3、注意next[i]实际上只在待匹配串的i位置之前
4、总的复杂度控制在o(n),其中n是source的规模
5、关键要理解next状态向量组的构造,实际上就是求target中每一位及前连续的前置位和从target起始位置开始及其后连续位置(到位置j)为相同的串的位置j。
代码:
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
using namespace std;
class KMPSolution {
public:
// Must give two paras
KMPSolution(string mSource, string mTarget) :
source(mSource),target(mTarget), tSize(target.size()) {}
void KMPMatch();
private:
void displayInfo(auto iter, string name);
void getNext();
string source, target;
int tSize;
vector<int> next, result;
};
void KMPSolution::getNext() {
int i = 0, j = -1;
next.push_back(j);
while(i < tSize) {
while(j>=0 && target[i] != target[j])
j = next[j];
i++; j++;
next.push_back(j);
}
}
void KMPSolution::KMPMatch() {
// Get the next array
getNext();
// Get the result
int i = 0, j = 1, sourceSize = source.size();
while (i < sourceSize) {
while (j >=0 && source[i] != target[j])
j = next[j];
i++; j++;
if (j == tSize) {
result.push_back(i - j);
j = next[j];
}
}
// Display The result
displayInfo(source, "Source");
displayInfo(target, "Target");
displayInfo(next, "next");
displayInfo(result, "result");
}
void KMPSolution::displayInfo(auto iter, string name) {
cout << "----------------------The " << name << " array------------------------" << endl;
for (auto it = iter.begin(); it != iter.end(); it++)
cout<<*it<<" ";
cout<<endl;
cout << "--------------------------------------------------------------" << endl;
cout<<endl<<endl;
}
int main() {
string source = "abcdefabcdefabcdefabcabcdkkljfabcdefabc";
string target = "abcdefabc";
KMPSolution kslo(source, target);
kslo.KMPMatch();
system("pause");
return 0;
}