数据结构(C语言)-串子系统(实验)

1、实验目的

(1)掌握串的特点及其存储方式
(2)用顺序存储结构实现一个串
(3)掌握串的查找、定位、连接、插入子串、删除子串等各个操作

2、实验内容

(1)定义一个存储顺序串的类型
(2)编写插入、删除、查找等所有基本函数
(3)设计如下选择式菜单,以选择菜单方式进行操作,将上述各种算法实现。
在这里插入图片描述

3、源程序(仅供参考)

//顺序串 
#include<stdio.h>
#include<stdlib.h>
typedef struct{
	char Data[100];//定义字符串的总大小
	int len;//记录字符串长度
}String;
int Long(String *s){//求字符串长度
	int i=0;
	while(s->Data[i]!='\0'){
		i++;
	}
	s->len=i;
	return(s->len);//返回串长 
}
void Establish(String *s){//建立字符串
	printf("输入元素:");
	gets(s->Data);//输入元素
	s->len=Long(s); //求长度
	if(s->len>0){//判断创建是否成功
		printf("String创建成功!"); 
	}else{
		printf("String创建失败!!!"); 
	}
}
void SubString(String *s,String *Sud){//求子串函数,String *Sud定义存放子表元素 
	int pod;//定义变量pod表示位置
	int i,len;//定义len子串长度
	printf("输入开始求子串的位置:");
	scanf("%d",&pod);
	printf("\n输入子串长度:");
	scanf("%d",&len);
	if(pod<1||pod>s->len||len<1||len>s->len-pod+1){//判断所开始查找的位置是否在主串上,如果在就执行else里的语句,如果不在吧Sud置空输出错误信息结束。 
		Sud->len=0;
		printf("\n参数错误!!");
	}else{
		for(i=0;i<len;i++){
			Sud->Data[i]=s->Data[pod+i-1];//把pod位置上的元素赋值给Sud串上的第一个位置 
		}
		Sud->Data[i]='\0';//Sud尾部加上结束标志 
		Sud->len=len;//把len输入的长度赋值给Sud串的len,表示子串长度 
		if(Sud->len<len){//如果Sud的长度小于输入len 在输出错误 结束程序 ,反之输出子表元素 
			printf("发生错误!!");
			exit(1); 
		}else{
			printf("\n子串元素为:");
			for(i=0;i<len;i++){
				printf("%5c",Sud->Data[i]);
			}
		}
	}
}
void StrDelete(String *s){
	int j,k,l,x,i,y;
	printf("输入子串删除的位置:");
	scanf("%d",&j);
	printf("\n输入删除子串的长度:");
	scanf("%d",&l);
	x=s->len;//把串长赋值给X变量 
	if(j+l-1>s->len){//删除的位置加上删除子串的长度如果大于主串则报错退出程序 
		printf("\n子串越界!!"); 
		exit(1);
	}else{
		y=s->len;
		for(k=j+l-1;k<y;k++,j++){//从第j个位置开始删除长度l的子串 
			s->Data[j-1]=s->Data[k];
			s->len--;
		} 
		s->Data[s->len]='\0';//尾部结束标志 
	}
	if(s->len>x){//如果串长大于删除之前的串长则报错,退出程序 
		printf("\n删除错误!!");
		exit(1);
	}else{
		printf("\n删除成功。");//删除成功,输出删除后的串 
		printf("\n删除后的串:"); 
		for(i=0;i<s->len;i++){
			printf("%5c",s->Data[i]);
		}
	}
}
void StrInsert(String *s ,String *s1){//插入子串的操作 
	printf("创建子串:");  
	gets(s1->Data);//给子串s1赋值 
	int i,k;
	k=0;
	while(s1->Data[k]!='\0'){//计算子串S1长度 
		k++;
	}
	s1->len=k;//把计算得到s1长度的K赋值给len 
	printf("输入插入子串的位置:");
	scanf("%d",&i);
	if(i>s->len){//如果插入子串S1的位置大于主串S,则直接报错 退出程序 
		printf("插入子串的位置错误!");
		exit(1); 
	}
	else if(s->len+s1->len>100){//如果插入S1和主串S大于最大分配空间,则直接报错,退出程序 
		printf("\n错误!串超过存储空间!!");
		exit(1); 
	}else{
		for(k=s->len-1;k>=i-1;k--){//将第i位开始向后移动S1长度 
			s->Data[s1->len+k]=s->Data[k];
		}
		for(k=0;k<s1->len;k++){//将s1插入到串S的第i为处 
			s->Data[i+k-1]=s1->Data[k];
		}
		s->len=s->len+s1->len;//修改S串的总长度 
		s->Data[s->len]='\0';//尾部加结束标志 
	}
	i=s->len;
	if(s->len==s->len-s1->len){//判断如果修改后的主串长度与修改前的主串长度相等则直接报错 
		printf("发错错误!!");
		exit(1);
	}else{
	printf("插入子串后的串:"); //输出插入子串后的串 
	for(k=0;k<i;k++){ 
		printf("%5c",s->Data[k]);
	} 
  }
	
}
void StrIndex_BF(String *s,String *t){//子串的定位操作 (模式匹配 BF算法) 
	printf("创建子串:");
	int i=0,j=0,k;
    gets(t->Data);
	while(t->Data[i]!='\0'){
		i++;
	}
	t->len=i;
	i=0;
	while(i<s->len&&j<t->len){ 
		if(s->Data[i]==t->Data[j]){//主串元素等子串元素 
			i++; 
			j++;
		}else{
			i=i-j+1;//如果不相等主串元素一项下一个元素,j归零重新比较 
			j=0;
		}
	}
	if(j>=t->len){//在串S中有串T 
			k=i-t->len+1;
			printf("子串在主串的%d位置!",k);
	}else{
			printf("主串上并没有找到该子串!");
	}
	 
}
void StrIndex_KMP(String *s,String *t){//子串的定位操作 (模式匹配 KMP算法)
	printf("创建子串:");
	 gets(t->Data);
	int i,j,l,k;
	i=0;
	j=1;
	int nextval[100];//T的next函数修正值并存入数组nextval 
	while(t->Data[i]!='\0'){
		i++;
	}
	t->len=i;
	l=0;k=1;
	nextval[1]=0;
	while(k<t->len){
		if(l==0||t->Data[k]==t->Data[l]){//t->Data[K]表示后缀,t->Data[l]表示前缀 
			++l;++k;
			if(t->Data[k]!=t->Data[l]){//如果当前字符与前缀不相同 
				nextval[k]=l;//则修正数组存放当前字符的前缀。 
			}else{
				nextval[k]=nextval[l];//如果与前缀字符相同,则将前缀字符的 nextval值赋值给nextval在i位置的值 
			}
	    }
	  	else {
			k=nextval[k];
		}
	}
	while(i<s->len&&j<t->len){
		if(j==0||s->Data[i]==t->Data[j]){
			i++;j++;
			
		}else{
			j=nextval[j];
		}
	}
	k=t->len;
	j=l=0;
	if(i>t->len){
		while(j<s->len){
			if(s->Data[j]==t->Data[l]&&l<=t->len){
			    k--;
			}
			j++;l++;
		}
		if(k==0){
		 printf("子串在主串的%d位置!",i-t->len+1);
		}else{
			 printf("主串上并没有找到该子串!");
		}
	}else{
		   printf("主串上并没有找到该子串!");
	}
}

void StrCompare(String *s,String *s1){
	printf("创建对比串:");
	gets(s1->Data);
	int i=0,floa=0;
	while(s1->Data[i]!='\0'){
		i++;
	}
	s1->len=i;
	i=0;
	if(s->len==s1->len){//判断长度是否相等,相等则进入下一步 
		while(s->len='\0'){//判断元素是否相等 
	       	if(s->Data[i]==s1->Data[i]){
	       		floa++;
			   }
	  	}
	  	if(floa==s->len==s1->len){
	  		printf("这个两字符串相等。");
		}
	}else{
		printf("两字符串不相等!!"); 
	}
}
void StrCat(String *s,String *t){//两串链接 
	printf("创建链接串:");
	gets(t->Data);
	int i=0;
	while(t->Data[i]!='\0'){
		i++;
	}
	t->len=i;
	if(s->len+t->len<=100){
		for(i=s->len;i<s->len+t->len;i++){
			s->Data[i]=t->Data[i-s->len];
		}
		s->Data[i]='\0';
		s->len=s->len+t->len;
		printf("链接后的串:");
		for(i=0;i<s->len;i++){
			printf("%5d",s->Data[i]);
		}
	}else if(s->len+t->len>100&&s->len<100){
		for(i=s->len,i<100;i++;){
			s->Data[i]=t->Data[i-s->len];
		}
		s->len=100;
		printf("链接后的串:");
		for(i=0;i<s->len;i++){
			printf("%5c",s->Data[i]);
		}
	}
	else{
		printf("出错了!!");
	}
	
}
void Menu(){
	printf("\n         字符串系统");
	printf("\n---------------------------------------------------------");
	printf("\n              1--创建串                                  ");
	printf("\n              2--求子串                                  ");
	printf("\n              3--插入子串                                ");
	printf("\n              4--删除子串                                ");
	printf("\n              5--BF算法定位串                            "); 
	printf("\n              6--KMP算法定位串                           ");
	printf("\n              7--判断两串是否相等                        ");
	printf("\n              8--两串链接                                ");
	printf("\n---------------------------------------------------------");
	printf("\n请输入 (0-8):"); 
}
int main(){
	String s,s1,Sud,t,v; 
	char ch1,ch2,a;
	ch1='y';
		while(ch1=='y'||ch1=='Y'){
		Menu();
		scanf("%c",&ch2);
		getchar();
		switch(ch2){
		    case '1':
		    	Establish(&s);
		    	break;
		    case '2':
		    	SubString(&s,&Sud);
		    	break;
		    case '3':
		    	StrInsert(&s,&s1);
		    	break;
		    case '4':
		    	StrDelete(&s);
		    	break;
		    case '5':
		    	StrIndex_BF(&s,&t);
		    	break;
		    case '6':
		    	StrIndex_KMP(&s,&t);
		    	break;
		    case '7':
				StrCompare(&s,&s1);
		    	break;
		    case '8':
		    	 StrCat(&s,&t);
		    	 break;
		  	case '0':
			    ch1='n';
				break;
			default:
			    printf("输入错误!!!!");  
		}
		if(ch2!='0'){
		    printf("\n按回车键继续,按任意键返回\n");
		}
			a=getchar();
		if(a!='\xA'){
				getchar();
				ch1='n';
		}
	}
} 

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值