#include<stdio.h>
#include<string.h>
#define OK 1
#define ERROR 0
#define MAXLEN 300
typedef int Status;
typedef char ElemType;
typedef struct{
int next[MAXLEN+1];
int nextval[MAXLEN+1];
char ch[MAXLEN+1];
int length;
}SString;
//初始化模式串
Status Init_S1(SString &S1)
{
S1.length=0;
return OK;
}
//初始化主串
Status Init_S2(SString &S2)
{
S2.length=0;
return OK;
}
//BF算法
int Index_BF(SString S,SString T,int pos)
{
//返回模式T在主串S中第pos个字符开始第一次出现的位置。若不存在,则返回值为0
//其中,T非空,1<=pos<=S.length
int i=pos; //初始化
int j=1;
int m=0;
while(i<=S.length&&j<=T.length) //两个串均未比较到串尾
{
if(S.ch[i]==T.ch[j]) //继续比较后继字符
{
++i;
++j;
}
else //指针后退,重新开始比较
{
i=i-j+2;
j=1;
}
m++;
}
printf("BF比较:%d次\t\t",m);
if(j>T.length)
{
return i-T.length; //匹配成功
}
else
{
return 0; //匹配失败
}
}
//KMP算法
int Index_KMP(SString S,SString T,int pos,int next[])
{
//利用模式串T的next函数求T在主串S中的第pos个字符之后的位置
//其中,T非空,1<=pos<=S.length
int i=pos;
int j=1;
int m=0; //m为比较次数
while(i<=S.length&&j<=T.length) //两个串均未比较到串尾
{
if(j==0||S.ch[i]==T.ch[j]) //继续比较后继字符
{
++i;
++j;
}
else //模式串向右移动
{
j=next[j];
}
m++;
}
printf("KMP比较:%d次\t\t",m);
if(j>T.length) //匹配成功
{
return i-T.length;
}
else //匹配失败
{
return 0;
}
}
//改进后的KMP算法
int NewIndex_KMP(SString S,SString T, int pos,int nextval[])
{ int i=pos,j=1,m=0;
while (i<=S.length &&j <=T.length)
{
if (j==0 ||S.ch[i]==T.ch[j]) { ++i ;++j; }
else j = nextval[j]; m++; /*i不变,j后退*/ }
printf("修正KMP算法比较:%d次 \t",m);
if (j>T.length) return i-T.length; /*匹配成功*/
else return 0;
}
//KMP算法中求next的函数值
void get_next(SString T,int next[])
{
//求模式串T的next函数修正值并存入数组next
int i=1;
next[1]=0;
int j=0;
while(i<T.length)
{
if(j==0||T.ch[i]==T.ch[j])
{
++i;
++j;
next[i]=j;
}
else
{
j=next[j];
}
}
}
//计算next函数的修正值
void get_nextval(SString T,int nextval[]){
//求模式串T的next函数修正值并存入数组nextval
int i = 1;
nextval[1]=0;
int j=0;
while(i<T.length)
{
if(j==0||T.ch[i]==T.ch[j])
{
++i;
++j;
if(T.ch[i]!=T.ch[j])
{
nextval[i]=j;
}
else
{
nextval[i]=nextval[j];
}
}
else
{
j=nextval[j];
}
}
}
int main()
{
char s1[300];
char s2[300];
SString S1;
SString S2;
Init_S1(S1);
Init_S2(S2);
printf("请输入主串:");
scanf("%s",&s2);
printf("请输入子串:");
scanf("%s",&s1);
//字符数组进入主串和模式串
for(int i=0;i<=strlen(s1)-1;i++)
{
S1.ch[i+1]=s1[i];
S1.length++;
}
for(int j=0;j<=strlen(s2)-1;j++)
{
S2.ch[j+1]=s2[j];
S2.length++;
}
//求结果
int next[60]={0};
int nextval[60]={0};
get_next(S1,next);
get_nextval(S1,nextval);
printf("next[]:");
for(int k = 1; k <= S1.length; k++)
printf("%d ", next[k]);
printf("\n");
printf("nextval[]:");
for(int r = 1; r <= S1.length; r++)
printf("%d ", nextval[r]);
printf("\n");
printf("Substring position:%d\n",Index_BF(S2,S1,1));
printf("Substring position:%d\n",Index_KMP(S2,S1,1,next));
printf("Substring position:%d\n",NewIndex_KMP(S2,S1,1,nextval));
}
Data Structure——KMP vs BF(串的应用:字符比较)
最新推荐文章于 2020-03-22 06:31:40 发布