/*
* Main.cpp
*
* Created on: Oct 7, 2015
* Author: chris
*/
#include<iostream>
#include<cstring>
using namespace std;
bool get_next(const char* pat, int*& next)
{
int len = strlen(pat);
next = new int[len];
if(!next) return false;
next[0] = 0;
int i = 1, j = 0;
while(i < len) {
if(pat[i] == pat[j]) { // matched.
++i; ++j; // move on.
next[i] = j; // record next.
} else if (j != 0){ // doesn't matched.
j = next[j]; // back trace.
} else { // nomatched.
next[i] = 0;
++i; // skip.
}
}//while
return true;
}
enum { INDS_INIT_SIZE = 10, INDS_INC_SIZE = 10};
bool Index_KMP(const char* str, const char *pat, int pos, int*& inds)
{
int *next = NULL;
if(!get_next(pat, next)) // prepare.
return false;
inds = new int[INDS_INIT_SIZE];
if(!inds) {
delete next;
return false;
}
inds[0] = INDS_INIT_SIZE; // arr size
inds[1] = 0; // num of matched ind
int i = pos, j = 0;
int Slen = strlen(str), Plen = strlen(pat);
while(i < Slen) {
if(str[i] == pat[j])
{ // matched.
++i; ++j; // move on.
if(j >= Plen)
{ // found.
int ind = i - Plen;
//record
if(inds[1] + 2 >= inds[0]) {
int*temp = new int[inds[0] + INDS_INC_SIZE];
if(!temp) {
delete inds;
delete next;
return false;
}
for(int i = 0; i < inds[0]; ++i)
temp[i] = inds[i];
delete inds;
inds = temp;
inds[0] += INDS_INC_SIZE;
}//realloc
inds[inds[1] + 2] = ind;
++inds[1];
j = 0; // continue.
}
} else if(j != 0) { // back trace.
j = next[j];
} else { // impossible.
++i;
}
}//while
delete next;
return true;
}
int main(void)
{
string str1, str2;
while(cin >> str1 >> str2) {
int* found = NULL;
if(Index_KMP(str1.c_str(), str2.c_str(), 0, found)){
int * data = found + 2;
for(int i = 0; i < found[1]; ++i)
cout << data[i] << " ";
cout << endl;
delete found;
} else
cout << "failed." << endl;
}
return 0;
}
C++实现KMP算法(C风格)
最新推荐文章于 2024-08-07 17:27:15 发布