您的位置:首页 > 其它

DataStructure-5-字符串

2015-08-03 23:35 465 查看
5.1 朴素的模式匹配算法(BF算法(Brute Force))

5.1.1原理分析





5.1.2 代码实现

#include <stdio.h>

int BF(char S[],char T[]);

int main(void)

{

//主串

char S[] = "abcabcacb";

//模式串

char T[] = "abcac";

//匹配查找

printf("BF:%d\n",BF(S,T));

}

int BF(char S[],char T[])

{

int i=0,j=0;

//当S没有结束并且T也没有结束

while(S[i] != '\0' && T[j] != '\0')

{

if(S[i]==T[j])

{

i++;

j++;

}

else //i和j分别回溯

{

i = i-j+1;

j=0;

}

}

if(T[j]=='\0') //匹配成功,返回本次匹配的开始位置(不是下标)

{

return i-j+1;

}else{

return 0;

}

}

5.2 KMP算法

5.2.1 原理分析

基本思想:主串不回溯







版本一:j从0开始,next从-1开始 (我比较喜欢j从0开始

)




列如:主串S=“ababaababcb”, 模式T=“ababc”,则该模式的next值计算如下:



j=0时,next[0]=-1;
j=1时,此时j由0到j-1的串只有“a”,属于其他情况next[1]=0;
j=2时, 此时j由0到j-1的串有“ab”,T[0]!=T[1],则next[2]=0;
j=3时, 此时j由0到j-1的串有“aba”,T[0]=T[2],则next[3]=1;
j=4时, 此时j由0到j-1的串有“abab”,T[0] T[1]=T[2] T[3],则next[4]=2;

版本二:J从1开始,next从0开始:





2.5.2 KMP算法的实现

#include <stdio.h>

void GetNext(char T[],int *next);

int KMP1(char S[],char T[]);

int length(char L[]);

int main(void)

{

//主串

char S[] = "ababaababcb";

//模式串

char T[] = "ababc";

//匹配查找

printf("KMP1:%d\n",KMP1(S,T));

return 0;

}

/*求字符串长度*/

int length(char L[])

{

int i=0;

while(L[i] != '\0')

{

i++;

}

return i;

}

//*next数组*/

void GetNext(char T[],int *next)

{

int j=0,k=-1;

next[0]=-1;

while(j < length(T))

{

if(k==-1 || T[j] == T[k])

{

++j;

++k;

next[j]=k;

}else{

k=next[k];

}

}

}

int KMP1(char S[],char T[])

{

int i=0,j=0;

int next[5];

GetNext(T,next);

/*当S没有结束并且T也没有结束*/

while(i < length(S) && j < length(T))

{

if(j==-1 || S[i]==T[j])

{

++i;

++j;

}

else /*j回溯*/

{

j=next[j];

}

}

if(j >= length(T)) /*匹配成功,返回本次匹配的开始位置(不是下标)*/

{

printf("i=%d,j=%d,T[j]=%c \n",i,j,T[j]);

return i-j+1;

}else{

return 0;

}

}

改进kmp算法:

注:此处讲解j是从1开始的,只是演示思路,程序设计还是以j=0开始













有以上的思路理解,对kmp算法改进如下:
j

0

1

2

3

4

T

a

b

a

b

c

next[j]

-1

0

0

1

2

nextval[j]

-1

0

-1

0

2

#include <stdio.h>

void GetNextVal(char T[],int next[]);

int KMP2(char S[],char T[]);

int length(char L[]);

int main(void)

{

//主串

char *S = "ababaababcb";

//模式串

char *T = "ababc";

//匹配查找

printf("KMP2:%d\n",KMP2(S,T));

return 0;

}

/*求字符串长度*/

int length(char L[])

{

int i=0;

while(L[i] != '\0')

{

i++;

}

return i;

}

/*改进kmp算法的next数组*/

void GetNextVal(char T[],int next[])

{

int j=0,k=-1;

next[0]=-1;

while(j<length(T))

{

if(k==-1 || T[j] == T[k])

{

++j;

++k;

if(T[j] != T[k])

{

next[j]=k;

}else{

next[j]=next[k];

}

}else{

k=next[k];

}

}

}

int KMP2(char S[],char T[])

{

int i=0,j=0;

int next[5];

GetNextVal(T,next);

/*当S没有结束并且T也没有结束*/

while(i<length(S) && j<length(T))

{

if(j==-1 || S[i]==T[j])

{

++i;

++j;

}

else /*j回溯*/

{

j=next[j];

}

}

if(j>=length(T)) /*匹配成功,返回本次匹配的开始位置(不是下标)*/

{

return i-j+1;

}else{

return 0;

}

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