数据结构(超详细讲解!!)第十八节 串(堆串)

news2025/7/15 5:39:32

1.定义

假设以一维数组heap [MAXSIZE] 表示可供字符串进行动态分配的存储空间,并设 int start 指向heap 中未分配区域的开始地址(初始化时start =0) 。在程序执行过程中,当生成一个新串时,就从start指示的位置起,为新串分配一个所需大小的存储空间,同时建立该串的描述。这种存储结构称为堆结构。 此时,堆串可定义如下:

typedef  struct
{int   len; 
 int   start; 
} HeapString; 

其中len域指示串的长度, start域指示串的起始位置。借助此结构可以在串名和串值之间建立一个对应关系,称为串名的存储映象。系统中所有串名的存储映象构成一个符号表。 

 在C语言中,已经有一个称为“堆”的自由存储空间,并可用malloc()和free()函数完成动态存储管理。因此,我们可以直接利用C语言中的“堆”实现堆串。此时,堆串可定义如下:

typedef  struct
{  
    char  * ch;  
    int   len; 
} HString; 

2.基本操作

1.初始化

//初始化
HString * Init_HString( )
{	HString *s;	
	s = (HString *) malloc ( sizeof( HString ) );
 	s->len=0;
 	s->ch=NULL;
 	printf("初始化成功。\n");
	return s;	
}

2.录入

//录入
int Enter_SStrin(HString *s)
{char x;
int len;
printf("请输入字符串长度和元素:");
scanf("%d %c",&len,&x); 
s->ch=(char *) malloc ( len );
while(x!='#')
{
	s->ch[s->len] = x;	
	s->len=s->len+1;  
	scanf(" %c",&x);
}
printf("录入完成。\n");
	return 1;			/*入队成功,函数返回1*/
}

3.插入

//插入 
int StrInsert(HString *s,HString t) /* 在串s中序号为pos的字符之前插入串t */
{
int i,pos;
char *temp;
printf("请输入插入位置:");
scanf("%d",&pos); 
if (pos<0 || pos>s->len || s->len==0) return(0);
temp=(char *)malloc(s->len + t.len);
if (temp==NULL) return(0);
for (i=0;i<pos;i++) temp[i]=s->ch[i];
for (i=0;i<t.len;i++) temp[i+pos]=t.ch[i];
for (i=pos;i<s->len;i++) temp[i + t.len]=s->ch[i];
s->len+=t.len;
free(s->ch);s->ch=temp;
printf("插入成功\n");
return(1);
} 

4.删除

//串删除函数
int StrDelete(HString *s) /* 在串s中删除从序号pos起的len个字符 */
{
int i,pos,len;
char *temp;
printf("请输入删除位置和个数:");
scanf("%d %d",&pos,&len); 
if (pos<0 || pos>(s->len - len)) return(0);
temp=(char *)malloc(s->len - len);
if (temp==NULL) return(0);
for (i=0;i<pos;i++) temp[i]=s->ch[i];
for (i=pos;i<s->len - len;i++) temp[i]=s->ch[i+len];
s->len=s->len-len;
free(s->ch);s->ch=temp;
printf("删除成功\n");
return(1);
} 

5.遍历

//遍历 
void Printf(HString *s)
{int i;
for(i=0;i<s->len;i++)
{printf("%c",s->ch[i]);
}
printf("\n");
}

6.复制

//串复制函数 
int StrCopy(HString *s,HString t) /* 将串t的值复制到串s中 */
{
int i;
s->ch=(char *)malloc(t.len);
if (s->ch==NULL) return(0);
for (i=0;i<t.len;i++) s->ch[i]=t.ch[i];
s->len=t.len;
printf("复制完成。\n");
return(1);
} 

7.判空

//判空函数
int StrEmpty(HString s) /* 若串s为空(即串长为0),则返回1,否则返回0 */
{
if (s.len==0) {
	printf("堆串为空。\n");
	return(1);
}
else 
printf("堆串不为空。\n");
return(0);
} 

8.比较

//串比较函数
int StrCompare(HString s,HString t) /* 若串s和t相等, 则返回0; 若s>t, 则返回1; 若s<t, 则返回-1 */
{
int i;
for (i=0;i<s.len&&i<t.len;i++)  
    if (s.ch[i]!=t.ch[i]) 
	{
    if(s.ch[i]- t.ch[i]==0)
	printf("串s和t相等。\n");
	if(s.ch[i]- t.ch[i]>0)
	printf("串s大于t。\n");
	if(s.ch[i]- t.ch[i]<0)
	printf("串s小于t。\n");
		return(s.ch[i] - t.ch[i]);
	}
	if(s.len - t.len==0)
printf("串s和t相等。\n");
if(s.len - t.len>0)
printf("串s大于t。\n");
if(s.len - t.len<0)
printf("串s小于t。\n");	  	
return(s.len - t.len);
} 

9.求串长

//求串长函数
int StrLength(HString s) /* 返回串s的长度 */
{printf("串长为:%d\n",s.len);
return(s.len);
} 

10.清空

//清空函数 
int StrClear(HString *s) /* 将串s置为空串 */
{
if (s->ch!=NULL) free(s->ch);
s->ch=NULL;
s->len=0;
printf("清空完成。\n");
return(1);
} 

11.连接

//连接函数
int StrCat(HString *s,HString t) /* 将串t连接在串s的后面 */
{
int i;
char *temp;
temp=(char *)malloc(s->len + t.len);
if (temp==NULL) return(0);
for (i=0;i<s->len;i++)
    temp[i]=s->ch[i];
for (i=s->len;i<s->len + t.len;i++) 
    temp[i]=t.ch[i-s->len];
s->len+=t.len;
free(s->ch);s->ch=temp;
printf("连接完成。\n");
return(1);
} 

12.求子串

//求子串函数
HString *SubString(HString s) /* 将串s中序号pos起的len个字符复制到sub中 */
{
int i,pos,len;
HString *sub;	
	sub = (HString *) malloc ( sizeof( HString ) );
 	sub->len=0;
 	sub->ch=NULL;
printf("请输入子串起始位置,和子串长度:");
scanf("%d %d",&pos,&len); 
if (sub->ch!=NULL) free(sub->ch);
if (pos<0 || pos>s.len || len<1 || len>s.len-pos) 
   { sub->ch=NULL;
   sub->len=0;
   printf("子串位置不合法。\n");
   return(0);} 
else { 
   sub->ch=(char *)malloc(len); 
   if (sub->ch==NULL) return(0); 
   for (i=0;i<len;i++) 
   sub->ch[i]=s.ch[i+pos]; 
   sub->len=len;  
   printf("截取子串成功。\n");
   return(sub); 
   }
} 

13.定位

//定位函数 
int StrIndex(HString s,HString t) /* 求串t在串s中的位置 */
{
int i, j,pos;
printf("请输入在第几个元素之后进行查找:");
scanf("%d",&pos);
if (s.len==0 || t.len==0) 
{printf("s或t不存在。\n");
	return(0);
}
i=pos;j=0;
while (i<s.len && j<t.len)
   { if (s.ch[i]==t.ch[j]) 
     {
       i++;j++;
       } 
    else {
       i=i-j+1;j=0;
       }
    }
if (j>=t.len) 
{printf("串t首在s中的位置为:%d\n",i-j);
	return(i-j);
}
else 
printf("未在s中找到t。\n"); 
return(0);
} 

3.代码

 #include<stdio.h>
#include<malloc.h>

typedef  struct
{  
    char  * ch; 
    int   len; 
} HString; 


//初始化
HString * Init_HString( )
{	HString *s;	
	s = (HString *) malloc ( sizeof( HString ) );
 	s->len=0;
 	s->ch=NULL;
 	printf("初始化成功。\n");
	return s;	
}


//录入
int Enter_SStrin(HString *s)
{char x;
int len;
printf("请输入字符串长度和元素:");
scanf("%d %c",&len,&x); 
s->ch=(char *) malloc ( len );
while(x!='#')
{
	s->ch[s->len] = x;	
	s->len=s->len+1;  
	scanf(" %c",&x);
}
printf("录入完成。\n");
	return 1;			/*入队成功,函数返回1*/
}

//遍历 
void Printf(HString *s)
{int i;
for(i=0;i<s->len;i++)
{printf("%c",s->ch[i]);
}
printf("\n");
}


//插入 
int StrInsert(HString *s,HString t) /* 在串s中序号为pos的字符之前插入串t */
{
int i,pos;
char *temp;
printf("请输入插入位置:");
scanf("%d",&pos); 
if (pos<0 || pos>s->len || s->len==0) return(0);
temp=(char *)malloc(s->len + t.len);
if (temp==NULL) return(0);
for (i=0;i<pos;i++) temp[i]=s->ch[i];
for (i=0;i<t.len;i++) temp[i+pos]=t.ch[i];
for (i=pos;i<s->len;i++) temp[i + t.len]=s->ch[i];
s->len+=t.len;
free(s->ch);s->ch=temp;
printf("插入成功\n");
return(1);
} 


//串删除函数
int StrDelete(HString *s) /* 在串s中删除从序号pos起的len个字符 */
{
int i,pos,len;
char *temp;
printf("请输入删除位置和个数:");
scanf("%d %d",&pos,&len); 
if (pos<0 || pos>(s->len - len)) return(0);
temp=(char *)malloc(s->len - len);
if (temp==NULL) return(0);
for (i=0;i<pos;i++) temp[i]=s->ch[i];
for (i=pos;i<s->len - len;i++) temp[i]=s->ch[i+len];
s->len=s->len-len;
free(s->ch);s->ch=temp;
printf("删除成功\n");
return(1);
} 

//串复制函数 
int StrCopy(HString *s,HString t) /* 将串t的值复制到串s中 */
{
int i;
s->ch=(char *)malloc(t.len);
if (s->ch==NULL) return(0);
for (i=0;i<t.len;i++) s->ch[i]=t.ch[i];
s->len=t.len;
printf("复制完成。\n");
return(1);
} 


//判空函数
int StrEmpty(HString s) /* 若串s为空(即串长为0),则返回1,否则返回0 */
{
if (s.len==0) {
	printf("堆串为空。\n");
	return(1);
}
else 
printf("堆串不为空。\n");
return(0);
} 

//串比较函数
int StrCompare(HString s,HString t) /* 若串s和t相等, 则返回0; 若s>t, 则返回1; 若s<t, 则返回-1 */
{
int i;
for (i=0;i<s.len&&i<t.len;i++)  
    if (s.ch[i]!=t.ch[i]) 
	{
    if(s.ch[i]- t.ch[i]==0)
	printf("串s和t相等。\n");
	if(s.ch[i]- t.ch[i]>0)
	printf("串s大于t。\n");
	if(s.ch[i]- t.ch[i]<0)
	printf("串s小于t。\n");
		return(s.ch[i] - t.ch[i]);
	}
	if(s.len - t.len==0)
printf("串s和t相等。\n");
if(s.len - t.len>0)
printf("串s大于t。\n");
if(s.len - t.len<0)
printf("串s小于t。\n");	  	
return(s.len - t.len);
} 


//求串长函数
int StrLength(HString s) /* 返回串s的长度 */
{printf("串长为:%d\n",s.len);
return(s.len);
} 

//清空函数 
int StrClear(HString *s) /* 将串s置为空串 */
{
if (s->ch!=NULL) free(s->ch);
s->ch=NULL;
s->len=0;
printf("清空完成。\n");
return(1);
} 


//连接函数
int StrCat(HString *s,HString t) /* 将串t连接在串s的后面 */
{
int i;
char *temp;
temp=(char *)malloc(s->len + t.len);
if (temp==NULL) return(0);
for (i=0;i<s->len;i++)
    temp[i]=s->ch[i];
for (i=s->len;i<s->len + t.len;i++) 
    temp[i]=t.ch[i-s->len];
s->len+=t.len;
free(s->ch);s->ch=temp;
printf("连接完成。\n");
return(1);
} 

//求子串函数
HString *SubString(HString s) /* 将串s中序号pos起的len个字符复制到sub中 */
{
int i,pos,len;
HString *sub;	
	sub = (HString *) malloc ( sizeof( HString ) );
 	sub->len=0;
 	sub->ch=NULL;
printf("请输入子串起始位置,和子串长度:");
scanf("%d %d",&pos,&len); 
if (sub->ch!=NULL) free(sub->ch);
if (pos<0 || pos>s.len || len<1 || len>s.len-pos) 
   { sub->ch=NULL;
   sub->len=0;
   printf("子串位置不合法。\n");
   return(0);} 
else { 
   sub->ch=(char *)malloc(len); 
   if (sub->ch==NULL) return(0); 
   for (i=0;i<len;i++) 
   sub->ch[i]=s.ch[i+pos]; 
   sub->len=len;  
   printf("截取子串成功。\n");
   return(sub); 
   }
} 

//定位函数 
int StrIndex(HString s,HString t) /* 求串t在串s中的位置 */
{
int i, j,pos;
printf("请输入在第几个元素之后进行查找:");
scanf("%d",&pos);
if (s.len==0 || t.len==0) 
{printf("s或t不存在。\n");
	return(0);
}
i=pos;j=0;
while (i<s.len && j<t.len)
   { if (s.ch[i]==t.ch[j]) 
     {
       i++;j++;
       } 
    else {
       i=i-j+1;j=0;
       }
    }
if (j>=t.len) 
{printf("串t首在s中的位置为:%d\n",i-j);
	return(i-j);
}
else 
printf("未在s中找到t。\n"); 
return(0);
} 

  void menu()
{
printf("--------1.初始化s------\n"); 
printf("--------2.初始化t------\n"); 
printf("--------3.录入s--------\n"); 
printf("--------4.录入t--------\n"); 
printf("--------5.插入---------\n"); 
printf("--------6.删除---------\n"); 
printf("--------7.判空---------\n"); 
printf("--------8.复制---------\n"); 
printf("--------9.比较---------\n"); 
printf("--------10.求长度------\n"); 
printf("--------11.清空--------\n"); 
printf("--------12.连接--------\n"); 
printf("--------13.求子串sub---\n"); 
printf("--------14.定位-------\n");
printf("--------15.遍历s-------\n"); 
printf("--------16.遍历t-------\n"); 
printf("--------17.遍历sub-----\n"); 
printf("--------18.退出程序----\n");
}

int main()
{HString *s,*t,*sub;
int n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,a,quit=0;
menu();
while(1)
{
scanf("%d",&a);
switch(a)
{
case 1:s=Init_HString( );break;
case 2:t=Init_HString( );break;
case 3:n1=Enter_SStrin(s);break;
case 4:n2=Enter_SStrin(t);break;
case 5:n3=StrInsert(s,*t);break;
case 6:n4=StrDelete(s);break;
case 7:n5=StrEmpty(*s);break;
case 8:n6=StrCopy(s,*t);break;
case 9:n7=StrCompare(*s,*t) ;break;
case 10:n8=StrLength(*s);break;
case 11:n9=StrClear(s);break;
case 12:n10=StrCat(s,*t);break;
case 13:sub=SubString(*s);break;
case 14:n11=StrIndex(*s,*t);break;
case 15:Printf(s);break;
case 16:Printf(t);break;
case 17:Printf(sub);break;
case 18:quit=1;break;
default:printf("输入1~18之间的数字\n");break;
}
if(quit==1)
{break;
}
}
return 0;
 } 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1157775.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑上数据恢复的详细操作

在日常使用电脑过程中&#xff0c;我们可能会遇到数据丢失的情况。无论是因为误删除、格式化、病毒攻击还是硬件故障&#xff0c;数据恢复都是我们迫切需要解决的问题。本文将介绍电脑数据恢复的详细操作步骤&#xff0c;帮助读者在面临数据丢失时能够迅速地恢复重要文件。 一…

将WebP转换为GIF的各种图像转换器,当然是免费的方式

第 1 部分。什么是 WebP Web 图片格式 (WebP) 是一种图像格式&#xff0c;可为网站上的照片提供卓越的无损压缩。该网站将使用这种格式运行得更快&#xff0c;创建更小、更丰富的图像。此格式比 PNG 图像小 26%&#xff0c;比 JPEG 图像小 25-24%。这样一来&#xff0c;它使网站…

为什么说MES生产管理系统很难做到标准化

随着数字化时代的来临&#xff0c;企业运营方式的转型已成为一种必然趋势。在这种背景下&#xff0c;MES生产管理系统作为一种车间执行层面的管理系统&#xff0c;逐渐受到了广大企业的关注和应用。不过&#xff0c;在实施MES管理系统的推广和实践过程中&#xff0c;也面临着诸…

暴涨3倍!通过受感染 USB 窃密的事件愈发变多

2023 年上半年&#xff0c;Mandiant 观察到使用受感染 USB 驱动器窃取机密数据的事件至少增加了3倍。此前&#xff0c;Mandiant 披露了在菲律宾的一次攻击行动。本文将会介绍研究人员发现的两外两次基于 USB 驱动器的网络间谍行动。 CSDN大礼包&#xff1a;《黑客&网络安全…

损失函数(Loss Function)一文详解-回归问题常见损失函数Python代码实现+计算原理解析

前言 损失函数无疑是机器学习和深度学习效果验证的核心检验功能&#xff0c;用于评估模型预测值与实际值之间的差异。我们学习机器学习和深度学习或多或少都接触到了损失函数&#xff0c;但是我们缺少细致的对损失函数进行分类&#xff0c;或者系统的学习损失函数在不同的算法…

管理类联考——数学——汇总篇——知识点突破——代数——函数、方程、不等式——记忆——局部

局部用各种方法 按知识点汇总其各自记忆方法 整式&#xff1a;六大公式 函数&#xff1a;一元二次函数【图像&#xff08;形状&#xff0c;上下&#xff0c;交点&#xff09; ⟹ \Longrightarrow ⟹ △ △ △ ⟹ \Longrightarrow ⟹ 抛物线与x轴交点 ⟹ \Longrightarrow …

多种方法解决leetcode经典题目-LCR 155. 将二叉搜索树转化为排序的双向链表, 同时弄透引用变更带来的bug

1 描述 2 解法一: 使用list列表粗出中序遍历的结果&#xff0c;然后再依次处理list中的元素并且双向链接 public Node treeToDoublyList2(Node root) {if(rootnull)return root;Node dummynew Node(-10000);List<Node>ansnew ArrayList<>();dfs2(root,ans);Node p…

五款好用的数据备份软件推荐!

在当今信息时代&#xff0c;数据备份的重要性不言而喻。选择一款可靠的、功能强大的免费备份软件&#xff0c;不仅能确保数据的安全存储&#xff0c;还能为用户节省宝贵的时间和精力。针对这一需求&#xff0c;精心挑选了几款备受推荐的免费数据备份软件&#xff0c;它们不仅操…

python爬取豆瓣电影Top250数据

本次爬虫案例使用Python语言编写&#xff0c;使用了requests库进行网页请求&#xff0c;使用了BeautifulSoup库进行网页解析&#xff0c;使用了openpyxl库进行数据的保存。 案例中的爬虫目标是豆瓣电影Top250&#xff0c;通过循环访问不同页面进行数据的爬取。在每个页面上&am…

新生儿积食:原因、科普和注意事项

引言&#xff1a; 新生儿积食&#xff0c;也被称为新生儿喂养问题&#xff0c;是新父母常常面临的挑战之一。尽管它通常是一种暂时的问题&#xff0c;但它可能会引起婴儿的不适&#xff0c;导致家长感到担忧。本文将科普新生儿积食的原因&#xff0c;提供相关信息&#xff0c;…

TypeScript之泛型

一、是什么 泛型程序设计&#xff08;generic programming&#xff09;是程序设计语言的一种风格或范式 泛型允许我们在强类型程序设计语言中编写代码时使用一些以后才指定的类型&#xff0c;在实例化时作为参数指明这些类型 在typescript中&#xff0c;定义函数&#xff0c;…

数据库的关系运算集合运算

目录 传统的关系运算&#xff1a; 0.相容性&#xff1a; 1.并&#xff1a; 2.差&#xff1a; 3.交&#xff1a; 4.笛卡尔积&#xff1a; 图例&#xff1a; 专门的关系运算&#xff1a; 选择&#xff1a; 投影&#xff1a; 连接&#xff1a; 自然连接&#xff1a; …

nodejs国内镜像及切换版本工具nvm

淘宝 NPM 镜像站&#xff08;http://npm.taobao.org&#xff09;已更换域名&#xff0c;新域名&#xff1a; Web 站点&#xff1a;https://npmmirror.com Registry Endpoint&#xff1a;https://registry.npmmirror.com 详见&#xff1a; 【望周知】淘宝 NPM 镜像换域名了&…

公司老项目springmvc jsp 自定义多数据源 转到springboot 整理

真实完整步骤&#xff0c;踩坑整理 有同样的坑&#xff0c;欢迎补充整理 网上的案例老是少了很多配置&#xff0c;本案例涉及到 spring-mvc&#xff0c;自定义多数据源&#xff0c;统一前缀&#xff0c;事务&#xff0c;mybatis&#xff0c;jsp访问异常&#xff0c;静态文件。…

高等数学啃书汇总重难点(九)多元函数微分法及其应用

下册最重要也是个人认为偏恶心的一节&#xff08;主要东西是真不少....&#xff09;重点在于会计算偏导、能理解全微分及隐函数求导3个核心内容&#xff0c;至于后面的关于几何层面的应用&#xff0c;建议掌握计算方法即可&#xff0c;学有余力再死磕推导过程等内容~ 1.平面点集…

Vue ElementUI el-tooltip 全局样式修改

el-tooltip 要点 此处是全局配置&#xff1b;如果想设置指定的 tooltip 可设置属性 popper-class&#xff0c;为 tooltip 的 popper 添加类名&#xff1b;代码 6 - 8 行&#xff0c;隐藏小三角&#xff1b; .el-tooltip__popper {border-radius: 4px !important;color: #9E9…

基于黑猩猩算法的无人机航迹规划-附代码

基于黑猩猩算法的无人机航迹规划 文章目录 基于黑猩猩算法的无人机航迹规划1.黑猩猩搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用黑猩猩算法来优化无人机航迹规划。 1.黑猩猩…

社交善行:TikTok如何引领慈善浪潮

在当今数字时代&#xff0c;社交媒体平台已成为人们互动、分享和传播信息的主要渠道。然而&#xff0c;这些平台不仅仅是用来社交和娱乐的工具&#xff0c;它们还可以成为慈善事业的有力支持者。 其中&#xff0c;TikTok以其独特的社交性质和广泛的用户群体&#xff0c;成为引…

东初版 java代码混淆 java加密class Java混淆实际方案

作为资深的开发专家&#xff0c;我很高兴与您分享有关Java混淆的实际方案和案例。Java混淆是一种重要的安全措施&#xff0c;用于保护您的代码免受恶意分析和反编译的威胁。在本文中&#xff0c;我将介绍Java混淆的基本原理、常用工具&#xff0c;以及一个简单的案例来演示如何…

Java如何使用KEPserver 实现S71500 OPC通信

一.PLC和OPC 使用的PLC&#xff1a;西门子PLC S7-1500 使用的OPC server软件&#xff1a; KEPServer V6 二.连接测试 OPC是工业控制和生产自动化领域中使用的硬件和软件的接口标准&#xff0c;以便有效地在应用和过程控制设备之间读写数据。O代表OLE(对象链接和嵌入)&am…