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

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,一经查实,立即删除!

相关文章

kotlin中集合操作符

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

python科研绘图:条形图

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

基于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…

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 服务&…

服务熔断保护实践--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…

小程序day02

目标 WXML模板语法 数据绑定 事件绑定 那麽問題來了&#xff0c;一次點擊會觸發兩個組件事件的話&#xff0c;該怎么阻止事件冒泡呢&#xff1f; 文本框和data的双向绑定 注意点: 只在标签里面用value“{{info}}”&#xff0c;只会是info到文本框的单向绑定&#xff0c;必须在…

【项目源码解析】某3C产品自动光学检测系统

解决方案源码解析思维导图 一、带有桁架机械手的自动光学检测系统介绍 二、关于机械手运动控制&#xff08;是否需要机器人学方面的知识&#xff09; 机械手的运动控制不需要深入了解机器人学方面的知识的情况包括&#xff1a; 预配置和任务单一性&#xff1a;如果机械手已经预…

Unity地面交互效果——2、动态法线贴图实现轨迹效果

Unity引擎动态法线贴图制作球滚动轨迹 大家好&#xff0c;我是阿赵。   之前说了一个使用局部UV采样来实现轨迹的方法。这一篇在之前的基础上&#xff0c;使用法线贴图进行凹凸轨迹的绘制。 一、实现的目标 先来回顾一下&#xff0c;上一篇最终我们已经绘制了一个轨迹的贴图…

NI‑9237国产化50 kS/s/ch,桥模拟输入,4通道C系列应变/桥输入模块

50 kS/s/ch&#xff0c;桥模拟输入&#xff0c;4通道C系列应变/桥输入模块 NI‑9237提供了所有的信号调理功能来实现多达四个基于桥的传感器的供电和测量。该模块提供通道间零相位延迟的应变或负载测量。它还具有60 VDC隔离和1&#xff0c;000 Vrms瞬态隔离&#xff0c;提供高…

java基础--多线程学习

写在前面&#xff1a; 多线程在面试中问的很多&#xff0c;之前没有过系统的学习&#xff0c;现在来进行一个系统的总结学习 文章目录 基础java多线程实现无参无返回值线程快速创建start和run方法的探讨run方法线程状态 有返回值线程线程池执行小结关于抛出异常的扩展 线程方…

云安全—kubelet攻击面

0x00 前言 虽然说总结的是kubelet的攻击面&#xff0c;但是在总结攻击面之前还是需要去了解kubelet的基本原理&#xff0c;虽然说我们浅尝即止&#xff0c;但是还是要以能给别人讲出来为基本原则。 其他文章: 云安全—K8s APi Server 6443 攻击面云安全—K8S API Server 未授…