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

C++实现KMP算法(C风格)

2015-10-07 17:05 489 查看
/*
* 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: