实验项目四:串基本操作的实现
课程名称:数据结构
实验项目名称:串基本操作的实现
实验目的:
1.掌握串的模式匹配操作。
实验要求:
1、 分别使用BF和KMP算法完成串的模式匹配。
实验过程:
BF算法代码;;
1、 设计完成next值的计算函数;
2、 设计完成修正next值的函数;
3、 KMP算法代码;
4、 输入子串(aaac)和主串(aaabaaaaaac)
5、 输出子串在主串中开始的位置及不同算法比较的次数。
此部分实验报告中给出BF,next,修正next,KMP的代码。
实验结果:
输入: 子串:aaac; 主串:aaabaaaaaac
输出:BF,KMP,改进的KMP三种算法分别比较的次数及查找到的子串在主串中的位置。
例:
BF比较??次 子串位置:8
KMP比较??次 子串位置:8
改进KMP比较??次 子串位置:8
实验分析:
1.普通next和修正next的区别;
2.列举调试运行过程中出现的错误并分析原因。
要求:
(1) 程序要添加适当的注释,程序的书写要采用缩进格式。
(2) 程序要具在一定的健壮性,即当输入数据非法时,程序也能适当地做出反应。
(3) 程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。
(4) 上传源程序到课堂派。顺序表的源程序保存为Stringindex.cpp。
算法讲解视频在MOOC上,西安邮电的数据结构课程
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
#define pi acos(-1.0)
#define e exp(1.0)
typedef long long ll;
char S[1200],T[1200];
ll Next[1200],nextval[1200],lens,lent,cnt_BF,cnt_next,cnt_nextval;
void Get_next(char *T)//得到next的值
{
ll j,k;
j=1,k=0;
Next[1]=0;
while(j<lent)
{
if(k==0||T[j]==T[k])
{
j++;
k++;
Next[j]=k;
}
else
k=Next[k];
}
return ;
}
void Get_nextval(char *T)//得到nextval的值
{
Get_next(T);
ll j=2,k;
nextval[1]=0;
while(j<=lent)
{
k=Next[j];
if(T[k]==T[j])
nextval[j]=nextval[k];
else
nextval[j]=k;
j++;
}
return ;
}
ll BF(char *S,char *T)//暴力匹配
{
ll i,j,k;
for(i=1;i<=lens-lent+1;i++)
{
k=i;
j=1;
while(j<=lent)
{
cnt_BF++;
if(S[k]==T[j])
{
k++;
j++;
}
else
break;
}
if(j>lent)
return i;
}
return 0;
}
ll KMP_next(char *S,char *T)//使用next值用KMP算法进行匹配
{
Get_next(T);
ll i,j,k;
i=1,j=1;
while(i<=lens&&j<=lent)
{
cnt_next++;
if(j==0||S[i]==T[j])
{
i++;
j++;
}
else
j=Next[j];
}
if(j>lent)
return i-lent;
return 0;
}
ll KMP_nextval(char *S,char *T)//使用nextval值用KMP算法进行匹配
{
Get_nextval(T);
ll i,j,k;
i=1,j=1;
while(i<=lens&&j<=lent)
{
cnt_nextval++;
if(j==0||S[i]==T[j])
{
i++;
j++;
}
else
j=nextval[j];
}
if(j>lent)
return i-lent;
return 0;
}
int main()
{
// freopen(".../.txt","w",stdout);
// ios::sync_with_stdio(false);
// puts("请输入母串和字串:");
// scanf("%s",S+1);
scanf("%s",T+1);
ll i,j;
// lens=strlen(S+1);
lent=strlen(T+1);
Get_nextval(T);
// for(i=1;i<=lent;i++)
// cout<<nextval[i]<<' ';
cnt_BF=0;//分别对三种匹配策略统计比较的次数
cnt_next=0;
cnt_nextval=0;
ll pos;
pos=BF(S,T);
pos=KMP_next(S,T);
pos=KMP_nextval(S,T);
if(pos==0)
puts("匹配失败");
else
{
puts("匹配成功,匹配位置为:");
printf("%d\n",pos);
printf("BF的比较次数为%d\n",cnt_BF);
printf("KMP_next的比较次数为%d\n",cnt_next);
printf("KMP_nextval的比较次数为%d\n",cnt_nextval);
}
return 0;
}