数据结构 实验报告三 串

该实验旨在掌握串的顺序存储结构和KMP算法,包括串的初始化、求子串、判等、求串长等功能。实验中遇到了下标转换、参数传递和子串长度错误等问题,通过调整代码得以解决。实验提供了源程序,包括字符串长度计算、字符串比较、子串截取和KMP字符串匹配等函数的实现。
摘要由CSDN通过智能技术生成

实验三 串

一、实验目的及要求

1.实验目的

1)掌握串的概念、抽象数据类型和特点,掌握串的顺序存储结构的存储思想及其程序实现,掌握串的各种基本操作。

2.实验要求

1)用结构体类型描述串的存储结构,对可能出现的问题预先分析,确定调试步骤和测试方法,编写源程序,尽可能考虑算法的健壮性,对实验中出现的问题进行分析、总结,完成实验报告。

2)上机过程中要遵守实验室的各项规章制度,爱护实验设备,保持环境卫生。

3)本课程的实验过程中,不得进行游戏、上网等操作。

二、实验环境(工具、配置等)

​ 1.硬件要求:计算机一台。

​ 2.软件要求:Windows11操作系统,使用C++语言,编译环境Dev-C++。

​ 3.数据结构与算法分析书一本,采用C++11标准。

三、实验内容(实验方案、实验步骤、设计思路等)

1. 实验方案:
  • 根据课本和老师课堂中讲解的内容,编写具体函数实现子串位置的定位函数,例如编写串的判等、求串长、求子串等操作函数实现,完成实验报告。
2.实验步骤:
  • 1)先编写具体代码实现串的顺序存储。

  • 2)进行求取KMP算法中next数组和nextval数组代码的编写

  • 3)编写实现求取子串的函数。

  • 4)进行串的判等的函数和求串长函数的编写。

    3.设计思路:
  • 先实现串的顺序存储,然后编写具体函数,最后书写主函数中调用函数,检查结果是否正确。

四、实验结果与分析

实验结果

1.实现串的顺序存储,然后实现KMP算法中子串的定位函数,效果如图4-1:

在这里插入图片描述

​ 图4-1 链栈输出结果

2.使用编译软件编写具体函数,实现具体功能,并检验程序是否编译运行成功,如图4-2:

在这里插入图片描述

​ 图4-2 程序输出结果

实验分析:

1.实验遇到的问题:

1)编写的串的顺序存储,在初始化时其下标从0开始,而匹配时下标从1开始,不知如何转换。

2)在编写KMP匹配算法时,next数组的传参出现问题。

3)编写截取子串函数时,出现输出的子串大于想要求取的子串长度。

2.问题解决的方法:

1)针对遇到的问题1,在输入时直接让其从下标为1开始输入,如cin>>(s.th)+1;。

2)针对遇到的问题2,将next数组设计为全局变量即可。

3)针对遇到的问题3,检查函数体时,发现是截取的子串的初始长度未设置为0,更改后程序正常运行。

五、源程序

#include<iostream>

using namespace std;

#define MAX_SIZE 100                     //串的最大长度 

typedef struct {
	char ch[MAX_SIZE+1];                 //存储串的一维数组 
	
	int S_length;                        //串的长度 
}Str_ing;

int Next[MAX_SIZE];                     //定义next数组 
int nextval[MAX_SIZE];                  //定义nextval数组 

//求取字符串的长度 
int Str_length(Str_ing T){
	
	int i=1;
	while(T.ch[i]!='\0'){
		i++;
	}
	
	return i-1;                         //输入直接从下标为1输入,所以减1 
} 

//两个字符串判等 
void Str_cmp(Str_ing S,Str_ing T){
	bool flag=true;
	if(S.S_length!=T.S_length){
		cout<<"两个字符串不相等!"<<'\n';
		return ;
	}
	else{
		for(int i=1;i<=S.S_length;i++){
			if(S.ch[i]!=T.ch[i]){
				flag=false;
				break;
			}
		}
		
		if(flag){
			cout<<"两个字符串相等!"<<'\n';
		}
		else{
			cout<<"两个字符串不相等!"<<'\n'; 
		}
	}
} 

//截取字符串 
void Str_sub(Str_ing S,int pos,int len){
	int i=0;
	Str_ing sub;
	sub.S_length=0;
	for(int i=0;i<len;i++){
		sub.ch[i]=S.ch[pos];
		pos++;
		sub.S_length++;
	}
	
	cout<<"截取后的子串为:";
	for(int i=0;i<sub.S_length;i++){
		cout<<sub.ch[i];
	}
}

//串的匹配 
int KMP_string(Str_ing S,Str_ing T,int x){
	int i=x,j=1; 
	
	int m=S.S_length,n=T.S_length;
	
	while(i<=m&&j<=n){
		if(j==0||S.ch[i]==T.ch[j]){
			++i;
			++j;
		}
		else{
			j=nextval[j];
		}
	}
	
	if(j>T.S_length){
		return i-T.S_length;
	}
	else{
		return 0;
	}
	
} 

//获取next数组 
void Get_Next(Str_ing T,int next[]){
	int i=1;
	next[1]=0;
	int j=0;
	int m=T.S_length;
	while(i<m){
		
		if(j==0||T.ch[i]==T.ch[j]){
			++i;
			++j;
			next[i]=j;
		}
		else{
			j=next[j];
		}
	}
	
}

//获取nextval数组 
void Get_nextval(Str_ing T,int nextval[]){
	int i=1;
	int j=0;
	nextval[1]=0;
	
	while(i<T.S_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(){
	
	Str_ing S,T;
	cout<<"请输入主串长度:";
	cin>>S.S_length;
	cout<<"请输入主串:";
	cin>>(S.ch)+1;
	cout<<"请输入匹子串长度:";
	cin>>T.S_length;
	cout<<"请输入子串:";
	cin>>(T.ch)+1;

	Get_Next(T,Next);
	Get_nextval(T,nextval);
	int x=KMP_string (S,T,1);
	
	cout<<"子串的定位为:"<<x<<'\n';
	
	cout<<"串的判等"<<"\n";
	Str_ing a,b,que,c;
	cout<<"请输入串1的长度和串:";
	cin>>a.S_length>>(a.ch)+1;
	cout<<"请输入串2的长度和串:";
	cin>>b.S_length>>(b.ch)+1; 
	Str_cmp(a,b);
	
	cout<<"请输入你想要的查询的串的长度和串:";
	cin>>que.S_length>>(que.ch)+1;
	cout<<"请输入你想要求的子串首位置和子串长度:";
	int pos,len;
	cin>>pos>>len;
	Str_sub(que,pos,len); 
	
	cout<<'\n';
	cout<<"请输入需要求取长度的字符串:"; 
	cin>>(c.ch)+1;
	int len2=Str_length(c);
	cout<<"字符串的长度为:"<<len2;
	 
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值