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

KMP 各版本实现代码

2011-11-14 23:02 337 查看
/*
* DA-Main-KMP.cpp
*
* 两种版本, 每个版本的 找一个子串 及 找所有子串
*
* 教材版 : 《数据结构域算法》 高等教育出版社 张铭等著 2008版
* 算法导论版 :《算法导论》第二版  及 《数据结构域算法》2004版
*
*  Created on: 2011-11-14
*/
#include <iostream>
#include <cstring>
using namespace std;

char Pattern[200], Str[200];
int next[200];

////////////////////////////////////////////
//教材版
////////////////////////////////////////////
void preKMP(char *P){        //优化
int j, k;
int len = strlen(P);

next[0] = -1;
j = 0, k = -1;
while(j < len - 1){
while(k >= 0 && P[j] != P[k]){
k = next[k];
}
k++, j++;

//不注的话是优化版
//        if(P[j] != P[k])
next[j] = k;
//        else
//            next[j] = next[k];
}
}

int KMP_1(char *T, char *P, int start){
int i, j;
int tLen = strlen(T);
int pLen = strlen(P);

i = start, j = 0;
while(i < tLen && j < pLen){
while(j >= 0 && T[i] != P[j]){
j = next[j];
}
i++, j++;
}
if(j >= pLen)
return i - pLen;
return -1;
}

int KMP_2(char *T, char *P, int start){
int i, j;
int tLen = strlen(T);
int pLen = strlen(P);

i = start, j = 0;
while(i < tLen && j < pLen){
if(j == -1 || T[i] == P[j])
i++, j++;
else
j = next[j];
}
if(j >= pLen)
return i - pLen;
return -1;
}

//找所有子串
void KMP_3(char *T, char *P, int start){
int i, j;
int tLen = strlen(T);
int pLen = strlen(P);

i = start, j = 0;
while(i < tLen){
while(j >= 0 && T[i] != P[j]){
j = next[j];
}

if(j == pLen - 1){
cout << i - j << endl;
j = next[j];
}
else                //注意加else!!!!!!!!!!!!!!!!!!!!!!!!!!!
i++, j++;
}
}

void KMP_4(char *T, char *P, int start){
int i, j;
int tLen = strlen(T);
int pLen = strlen(P);

i = start, j = 0;
while(i < tLen){
if(j == -1 || T[i] == P[j]){
if(j == pLen - 1){
cout << i - j << endl;
j = next[j];
}
else
i++, j++;
}
else
j = next[j];
}
}

////////////////////////////////////////
//算法导论版\04教材版 (注意 算法导论 中下标从1开始, 所以有所不同)
////////////////////////////////////////

void preKMP_CLRS(char *P){
int j, k;
int pLen = strlen(P);

next[0] = 0;
for(j=1; j<pLen; j++){
k = next[j-1];
while(k > 0 && P[j] != P[k])
k = next[k-1];        //下标从0开始,所以长度 = 下标 +1
if(P[j] == P[k])
k++;
next[j] = k;
}
}

int KMP_CLRS(char *T, char *P, int start){
int i, j;
int tLen = strlen(T);
int pLen = strlen(P);

j = 0;
for(i=start; i<tLen; i++){
while(j > 0 && T[i] != P[j]){
j = next[j-1];
}
if(T[i] == P[j])
j++;
if(j == pLen)
return i - j + 1;
}
return -1;
}

//找所有子串
void KMP_CLRS_2(char *T, char *P, int start){
int i, j;
int tLen = strlen(T);
int pLen = strlen(P);

j = 0;
for(i=start; i<tLen; i++){
while(j > 0 && T[i] != P[j]){
j = next[j-1];
}
if(T[i] == P[j]){
if(j == pLen - 1){
cout << i - j << endl;
j = next[j];
j--;        //注意:长度 = 下标 + 1
}
j++;
}
}
}

void test(){
cin >> Str >> Pattern;

preKMP(Pattern);

cout << "next : " << endl;
for(int i=0; i<strlen(Pattern); i++)
cout << next[i] << "";
cout << endl << endl;

cout << KMP_1(Str, Pattern, 0) << endl;
cout << KMP_2(Str, Pattern, 0) << endl;

cout << endl;
KMP_3(Str, Pattern, 0);
cout << endl;
KMP_4(Str, Pattern, 0);
cout << endl;

/////////////////////////////////
preKMP_CLRS(Pattern);

cout << "next_CLRS : " << endl;
for(int i=0; i<strlen(Pattern); i++)
cout << next[i] << "";
cout << endl << endl;

cout << KMP_CLRS(Str, Pattern, 0) << endl;
cout << endl;
KMP_CLRS_2(Str, Pattern, 0);

}

int main(){

test();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐