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

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.mzph.cn/news/127028.shtml

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

相关文章

AQS 框架、JUC常见并发包 简述

AQS&#xff08;AbstractQueuedSynchronizer&#xff09;是 Java 中的一个强大的同步框架&#xff0c;为我们提供了实现各种同步器的基础。在本篇博客中&#xff0c;我们将介绍 AQS 框架的基本原理&#xff0c;并探讨几个常见的 AQS 实现&#xff1a;ReentrantLock、CountDownL…

kotlin中集合操作符

集合操作符 1.总数操作符 any —— 判断集合中 是否有满足条件 的元素&#xff1b; all —— 判断集合中的元素 是否都满足条件&#xff1b; none —— 判断集合中是否 都不满足条件&#xff0c;是则返回true&#xff1b; count —— 查询集合中 满足条件 的 元素个数&#x…

python科研绘图:条形图

条形图&#xff08;bar chart&#xff09;是一种以条形或柱状排列数据的图形表示形式&#xff0c;可以显示各项目之间的比较。它通常用于展示不同类别的数据&#xff0c;例如在分类问题中的不同类别、不同产品或不同年份的销售数据等。 条形图中的每个条形代表一个类别或一个数…

easyexcel根据模板导出Excel文件,表格自动填充问题

背景 同事在做easyexcel导出Excel&#xff0c;根据模板导出的时候&#xff0c;发现导出的表格&#xff0c;总会覆盖落款的内容。 这就很尴尬了&#xff0c;表格居然不能自动填充&#xff0c;直接怒喷工具&#xff0c;哈哈。 然后一起看了一下这个问题。 分析原因 我找了自…

MySQL - 系统库之 performance_schema

performance_schema &#xff1a;用于收集和存储关于数据库性能和资源利用情况的信息&#xff0c;可用于监控、分析和优化数据库的性能&#xff1a; 用途&#xff1a; 性能监控&#xff1a;performance_schema 用于监控数据库的性能。它提供了有关查询执行、锁等待、I/O操作、…

基于goframe2.5.4、vue3、tdesign-vue-next开发的全栈前后端分离的管理系统

goframe-admin goframe-admin V1.0.0 平台简介 基于goframe2.5.4、vue3、tdesign-vue-next开发的全栈前后端分离的管理系统。前端采用tdesign-vue-next-starter 、vue3、pinia、tdesign-vue-next。 特征 高生产率&#xff1a;几分钟即可搭建一个后台管理系统认证机制&#x…

华为云资源搭建过程

网络搭建 EIP&#xff1a; 弹性EIP&#xff0c;支持IPv4和IPv6。 弹性公网IP&#xff08;Elastic IP&#xff09;提供独立的公网IP资源&#xff0c;包括公网IP地址与公网出口带宽服务。可以与弹性云服务器、裸金属服务器、虚拟IP、弹性负载均衡、NAT网关等资源灵活地绑定及解绑…

通过Google搜索广告传送的携带木马的PyCharm软件版本

导语 最近&#xff0c;一起新的恶意广告活动被发现&#xff0c;利用被入侵的网站通过Google搜索结果推广虚假版本的PyCharm软件。这个活动利用了动态搜索广告&#xff0c;将广告链接指向被黑客篡改的网页&#xff0c;用户点击链接后下载的并不是PyCharm软件&#xff0c;而是多种…

【代码数据】2023粤港澳大湾区金融数学建模B题分享

基于中国特色估值体系的股票模型分析和投资策略 首先非常建议大家仔细的阅读这个题的题目介绍&#xff0c;还有附赠的就是那个附件里的那几篇材料&#xff0c;我觉得你把这些内容读透理解了&#xff0c;就可以完成大部分内容。然后对于题目里它主要第一部分给出了常用的估值模…

AttributeError: partially initialized module ‘pandas‘ has no attribute ‘core‘

在使用jupyter notebook学习动手学深度学习时&#xff0c;出现以下错误&#xff1a; %matplotlib inline import math import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, num_steps 32, 35 train_iter, voca…

Linux命令(111)之groupadd

linux命令之groupadd 1.groupadd介绍 linux命令groupadd是用来创建新的用户组&#xff0c;用户组信息会被添加到系统文件(/etc/group)中。 2.groupadd用法 groupadd [参数] GroupName groupadd常用参数 参数说明-g指定用户组的gid号-r创建系统工作组-f如果组已经存在则成功…

android 8.1 disable unsupported sensor

如果device不支持某种sensor,可以在android/frameworks/base/core/java/android/hardware/SystemSensorManager.java里将其disabled掉。以disable proximity sensor为例。 public SystemSensorManager(Context context, Looper mainLooper) {synchronized(sLock) {if (!sNativ…

C#项目设计——学生成绩管理系统设计

学生成绩管理系统C语言.Net C#项目设计 全套代码加数据库文件&#xff0c;带设计报告&#xff0c;带设计报告哦&#xff01; 可以用Microsoft Visual Studio打开 用户名和密码在数据里。 报告部分内容&#xff1a; 设计一个学生成绩管理系统。包括“登录窗体”、“主窗体”和…

idea中启动多例项目配置

多实例启动 日常本地开发微服务项目时&#xff0c;博主想要验证一下网关的负载均衡以及感知服务上下线能力时&#xff0c;需要用到多实例启动。 那么什么是多实例启动嘞&#xff1f;简单说就是能在本地同时启动多个同一服务。打个比方项目中有一个 MobileApplication 服务&…

Android 13 - Media框架(13)- OpenMax(一)

这一节我们将了解Android OpenMax框架&#xff0c;该框架了解完成之后&#xff0c;我们会再回过头去了解 ACodec&#xff0c;将 MediaCodec - ACodec - OpenMax 连接起来&#xff0c;了解组件的创建控制以及 buffer 的流转。 本篇属于个人学习笔记&#xff0c;如有错误欢迎指出…

C# 使用.NET的SocketAsyncEventArgs实现高效能多并发TCPSocket通信

简介&#xff1a; SocketAsyncEventArgs是一个套接字操作得类&#xff0c;主要作用是实现socket消息的异步接收和发送&#xff0c;跟Socket的BeginSend和BeginReceive方法异步处理没有多大区别&#xff0c;它的优势在于完成端口的实现来处理大数据的并发情况。 BufferManager类…

服务熔断保护实践--Sentinal

目录 概述 环境说明 步骤 Sentinel服务端 Sentinel客户端 依赖 在客户端配置sentinel参数 测试 保护规则设置 设置资源名 设置默认的熔断规则 RestTemplate的流控规则 Feign的流控规则 概述 微服务有很多互相调用的服务&#xff0c;构成一系列的调用链路&#xf…

蜜罐系统HFish的部署与功能实测

1. 引入 根据参考1对蜜罐的定义&#xff1a; 蜜罐&#xff08;Honeypot&#xff09;是一个计算机科学领域的术语&#xff0c;指用于检测或防御未经授权的行为或黑客攻击的陷阱。其名称来源于其工作原理类似于用来诱捕昆虫的蜜罐。蜜罐通常伪装成看似有利用价值的网路、资料、…

3.15每日一题(分部积分求不定积分)

解法一&#xff1a;令lnx等于t&#xff1b;求出x与t的关系&#xff0c;带入f(lnx)的式子中&#xff1b;通过凑微分&#xff0c;分部积分等方法求出答案 注&#xff1a;在分部积分后&#xff0c;求不定积分时 &#xff08;1&#xff09;可以加项减项拆的方法求&#xff08;常规…

61. 旋转链表、Leetcode的Python实现

博客主页&#xff1a;&#x1f3c6;李歘歘的博客 &#x1f3c6; &#x1f33a;每天不定期分享一些包括但不限于计算机基础、算法、后端开发相关的知识点&#xff0c;以及职场小菜鸡的生活。&#x1f33a; &#x1f497;点关注不迷路&#xff0c;总有一些&#x1f4d6;知识点&am…