数据结构---串(整个部分)

news/2024/4/29 7:55:50/文章来源:https://blog.csdn.net/weixin_63032791/article/details/127795508

串基本概念:串是由零个或者多个字符组成的有限序列,一半记作S='a1,a2,a3,a4.......'(n>=0,串的长度)

1.S == 串的名字     n ==  串当中字符串的个数,称为串的长度。

串的常用术语

1.空串(null string):长度为零的串,它不包含任何字符。

2.空格串(black string) :任由一个或多个空格组成的串,长度大于等于1

3.子串(sub string):串中任意个连续字符的组成的子序列称为该串的“子串”

4.主串(master string):包含子串的串相应的称为“主串”,因此子串是主串的一部分。

5.前缀子串(prefix sub string):S的前缀子串是一个子串U,记作U = 'a1,.....ab'(1<=b<=n),当1<=b<n时,则相应的U称为S的“真前缀子串”。

6.后缀子串(suffix sub string):S的后缀子串是一个子串U,记作U = 'an-b-1....an'(1<=b<=n),当1<=b<n时,

eg.S='abccset',S的前缀子串是‘a’,'ab','abc','abcc','abccs','abccse'。S的后缀子串是‘t’,'et','set','cset','ccset','bccset'。

7.位置:通过将字符在串中的序号,称为该字符在串中的“位置”。子串在主串中的位置则以子串的第一个字符在主串中的位置来表示。

8.串相等:当且仅当两个串的值相等的时候,则称两个串的数值相等。条件:长度相等以及位置必须相等

9.模式匹配:确定子串在主串的某个位置开始后,在主串中首次出现的位置的运算。主串=="目标串",子串==“格式串”。

eg. 串A = “abcaabsbcas”,串B = "bca",从第一个位置开始,匹配的运算结果是2,从第四个位置开始的运算结果是8。

串的基本运算

 1.strInsert(S,pos ,T)

设S='chater',T=‘rac’,运行StrInsert(S,4,T),S='character'

2.strDelete(S.pos,len)

设S='chapter',运行StrDelete(S,5,3),则S='chap'

3.StrCat(S,T)

设串S='man',运行Strcat(S,'kind'),则S='mankind'

4.Substring(T,S,pos,len)

eg.设串S='commander',运行SubString(Sub1,S,4,3),则Sub1='man'。

5.StrIndex(S,pos,T)

设S='abcaabcaaabc',T='bca',运行StrIndex(S,1,T),返回2,运行StrIndex(S,4,T),返回值是 6。

6.StrReplace(S,T,V)

eg.设S='abcaabcaaabca',T='bca',若V='x',则S='axaxaax',若V='bc',则S='abcancaabc'

串的存储结构以及实现

 定义顺序串

1.定长顺序串存储结构

#define MAXSIZE 50
typedef struct
{char ch[MAXSIZE+1];       //0号元素不使用(浪费一个空间),每个分量存储一个字符。int len;
}SString;

 串的实际长度可以在MAXSIZE范围内随意变动,超过范围的会舍去,称为“截断”。

2.定长串的基本操作实现

插入:三种情况

int SStrInsert(SString *S,int pos,const SSttring T)
{int i;if(pos<1 || pos >S->len+1)return 0;//插入的子串没有超过最大值且主串不需要舍弃 if(S->len + T.len<=MAXSIZE){for(i = S->len+T.len;i>=pos+T.len;i--){S->ch[i] = S->ch[i-T.len];}for(i = pos;i<S->len+T.len;i++){S->ch[i] = S->ch[i-pos+1]}S->len = S->len + T.len;}//子串可以完全插入,但是主串需要舍弃一部分 else if(pos+T.len<=MAXSIZE){for(i = MAXSIZE;i>=pos+T.len;i--){S->ch[i] = S->ch[i-T.len]}for(i = pos;i<S->len+T.len;i++){S->ch[i] = S->ch[i-pos+1]}S->len = MAXSIZE;} //子串插入在任意位置,都超出了最大范围 else{for(i = pos ;i<=MAXSIZE;i++){S->ch[i] = T.ch[i-pos+1]}S->len = MAXSIZE;}return 1;
}

删除函数:

int SStrDelete(SSting *S,int pos,int len)
{int i = 1;if(pos<1 || pos>S->len || len<0 || len>S->len-pos+1){return 0;}for(i = pos;i<S->len-len;i++){s->ch[i] =  S->ch[i+len]; }return 1;
} 

串的连接

1.连接后串长小于等于MaxSize,则直接连接在第一个串的后面。

2.连接后,当串长大于MaxSize,且原始串的长度小于MaxSize,则待连接串则会舍弃一部分,当原始串长==MaxSize,则将待连接串全部进行舍弃。

int SStrCat(SSting *S,const SString T)
{int i = 1;if(S->len+T.len<=MaxSize){for(i = S->len;i<=S->len+T.len;i++){S->ch[i] = S.ch[i-S->len];}S->len = S->len+T.len;}else if(S->len<MaxSize){for(i=S->len;i<=MaxSize;i++){S->ch[i] = S->ch[i-S->len]	}	S->len = MaxSize;}elsereturn 0;
}

堆串(相较于定长的顺序串,堆串可以动态的分配内存空间,这样可以保证不会出现截断的情况)

1.串的初始化 

void HSrInit(HString *S)
{S->ch = NULL;S->len = 0;
}HString;

2.串的赋值操作

int HstrAssign(HString  *S,const char * chars)
{int i = 0;while(char[i] != '\0')i++;S->len = i;if(0 != S->len){if(S->ch != NULL)free(S->ch);S->ch = (char *)malloc((S->len + 1) * sizeof(char));if(NULL == S->ch)return 0;for(i = 1;i<=S->len;i++){S->ch[i] = chars[i-1];}elseS->ch = NULL;return 1;}	
} 

3.串的插入

int HStrInsert(HString *S,int pos,const HString T)
{int i;char * temp;if(pos>S->len || pos<1)return 0;temp = (char *)malloc(sizeof(S->len+T.len + 1)*sizeof(char));if(temp == NULL)return 0;for(i = 0;i<pos;i++)temp[i] = S->ch[i];for(i = pos;i<pos+T.len;i++)temp[i] = S->ch[i-pos+1];for(i = pos+T.len;i<=S->len+T.len;i++)temp[i] = S->ch[i-T.len];free(S->ch)S->ch = temp;S->len+=T.len;return 1; 
}

4.串的删除

int HStrDelete(HString *S,int pos,int len)
{int i;char *temp;if(len<0 || pos<1 || pos>S->len-len+1)return 0;temp = (char *)malloc(sizeof(S->len-len+1) * sizeof(char));if(NULL == temp)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];free(S->ch);S->ch = temp;S->len-=len;return 1;
}

5.串的连接

int HStrCat(HString * S,const HString)
{int i = 1;S->ch = (char *)malloc(S->ch,(S->len +T.len +1)*sizeof(char));if(NULL == S->ch)return 0;for(i = S->len+1;i<=T.len+S->len;i++)S->ch[i] = T.ch[i-S->len];S->len = S->len + T.len;return 1;
}

块链串(链表的每一个结点存放一个字符或者多个字符,每个结点称为块,整个链表称为“块链结构”)

 块大小:块链表存放字符的个数

当块的大小 == 1的时候,增删改查的方法和单链表一样,因为只有一个数据域和一个指针域,但当块的大小 ≠ 1的时候,则需要进行结点的拆分和合并....

存储密度:存储密度 = 串值所占的存储位 / 实际分配的存储位

串的模式匹配

1.BF模式匹配算法 

思路:从主串的第一个字符开始进行匹配,当主串和子串的字符不相同的时候,就回溯到开始字符的下一个字符,重新开始进行匹配,知道找到为止

int indedx(SString S,int pos,SString T)
{int i = pos,j = 1;while(i<=S.len && j<=T.len){if(S.ch[i] == T.ch[j])i++,j++;else{i = i-j+2;    //返回到起始比较字符的下一位,重新开始判断j = 1;}}if(j > T.len)return i-T.len;elsereturn 0;
}

2.KMP模式匹配算法

思路:相对于暴力索引求解,KMP的时间复杂度大大降低,开始都是和BF算法一样,一个一个字符进行匹配,但当主串和子串的字符不相等的时候,不再是回到主串中开始比较字符的下一位,而是进行一个“子串向后移动最长前后缀相等子串长度”,最后找到对应的字符串。(详细介绍:数据结构KMP算法配图详解(超详细)_哈顿之光的博客-CSDN博客_kmp算法难吗是什么级别)

这里需要好好理解一下next数组的作用(记录当前字符的前面的最长前后缀相等的字符串)

首先将模式串的每一个字符对应的next的数值求出来

eg. "ABCABCKO"

 这样就得到了当前每一个字符对应的next数组的数值。

void Get_Next(SString T,int next[])
{int j = 1,k = 0;next[1] = 0;while(j < T.len){if(k == 0 || T.ch[j] == T.ch[k]){++j;++k;next[j] = k;}elsek = next[k];printf("%d \n",next[k]);}
}
int KMPIndex(SqString s,SqString t)  //KMP
{int next[MaxSize],i=0,j=0;GetNext(t,next);while (i<s.length && j<t.length) {if (j==-1 || s.data[i]==t.data[j]) {i++;j++;  			//i,j各增1}else j=next[j]; 		}if (j>=t.length)return(i-t.length);  	else  return(-1);        		
}

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

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

相关文章

七夕,程序员教你5个表白代码,2分钟学会,牢牢主抓她的心

七夕。一个有人欢喜有人愁的节日&#xff0c;虽然对一些单身人士不太友好&#xff0c;但还有不少人都在等这个节日进行表白。毕竟这个日子的成功率会高一些。 情人节少不了送花送礼物&#xff0c;作为一个程序员&#xff0c;当然不会在送什么礼物上给你指点一二&#xff0c;但…

掌控安全学院SOL注入靶场

掌控安全学院SOL注入靶场靶场地址Pass-01 显错注入Pass-02Pass-03Pass-04Pass-05 POST注入Pass-06Pass-07 Head注入Pass-08Pass-09Pass-10 布尔盲注Pass-11Pass-12Pass-13 延时注入Pass-14Pass-15 宽字节注入Pass-16Pass-17总结靶场地址 http://inject2.lab.aqlab.cn Pass-01…

Java实现图书管理系统

作者&#xff1a;~小明学编程 文章专栏&#xff1a;JavaSE基础 格言&#xff1a;目之所及皆为回忆&#xff0c;心之所想皆为过往 今天给大家带来的是用Java实现的图书管理系统。 目录 需求 图书类 创建图书类 创建书架 Operation IOperation接口 添加图书AddOperation…

【考研复试】计算机专业考研复试英语常见问题三(个人选择/学业规划篇)

相关链接&#xff1a; 【考研复试】计算机专业考研复试英语常见问题一&#xff08;家庭/家乡/学校篇&#xff09;【考研复试】计算机专业考研复试英语常见问题二&#xff08;研究方向/前沿技术/本科毕设篇&#xff09;【考研复试】计算机专业考研复试英语常见问题三&#xff0…

kubernetes集群基于kubeadm部署以及常见问题解决

文章目录集群类型主机规划环境初始化检查操作系统版本关闭防火墙设置主机名主机名解析时间同步关闭 SELinux关闭 swap 分区将桥接的IPv4流量传递到iptables的链开启ipvs安装容器运行时&#xff08;Docker&#xff09;卸载Docker旧版本&#xff1a;安装 gcc 相关安装Docker设置阿…

一个Adapter+recycleview实现多种布局,区分布局中

文章目录&#x1f353;&#x1f353;简述&#x1f353;&#x1f353;效果图&#x1f353;&#x1f353;代码&#x1f96d;&#x1f96d;AllAdapter.java&#x1f96d;&#x1f96d; FuritAdapter3.java&#x1f96d;&#x1f96d;MainActivity.java(主函数)&#x1f96d;&#…

【全网热点】打造全网最全爱心代码仓库【火速领取爱心】

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 本文章收录于专栏 【代码实践】 目录&#x1f319;正文&#x1f30f;部分效果在线演示&#x1f30f;部分效果截屏&#x1f338;文末祝…

个人设计web前端大作业 基于html5制作美食菜谱网页设计作业代码

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

Linux的前世今生

14天学习训练营导师课程&#xff1a; 互联网老辛《 符合学习规律的超详细linux实战快速入门》 努力是为了不平庸~ 学习有些时候是枯燥的&#xff0c;但收获的快乐是加倍的&#xff0c;欢迎记录下你的那些努力时刻&#xff08;学习知识点/题解/项目实操/遇到的bug/等等&#xf…

2022年深度学习最新研究成果

一、开源深度学习编译器 二、 开源深度学习加速器 三、AITemplate引擎 四、微型机器学习框架 参考文献&#xff1a;https://arxiv.org/pdf/1510.00149.pdf 五、Contrastive Learning 对比学习综述 六、Diffusion Model 扩散模型综述 Diffusion Models: A Comprehensive Surv…

Java面向对象中阶(七)

面向对象中阶 1、包 2、访问修饰符 3、封装 4、继承 5、方法重写(override) 6、多态 7、Object类的常用方法 8、断点调试 1、包 包的本质&#xff1a; 实际上就是创建不同的文件夹来保存类文件 包的三大作用&#xff1a; 区分相同名字的类当类很多时&#xff0c;可以…

【freeRTOS】操作系统之六-低功耗模式

六&#xff0c;低功耗模式 本章节为大家讲解 FreeRTOS 本身支持的低功耗模式 tickless 实现方法&#xff0c;tickless 低功耗机制是当前小型 RTOS 所采用的通用低功耗方法&#xff0c;比如 embOS&#xff0c;RTX 和 uCOS-III&#xff08;类似方法&#xff09;都有这种机制。ti…

原来背后都是商业利益,看到网易和暴雪的解约之后,原来是要定以后的KPI,坐地起价,但是一个时代已经结束了,都留在了记忆之中

1&#xff0c;大瓜新闻&#xff0c;2023年1月暴雪游戏中国将不会续约&#xff1f;&#xff1f; 2&#xff0c;原因是主要坐地起价&#xff0c;提高分成设置KPI 还好网易有自研游戏&#xff0c;估计早知道会有现在这样的情况。 提前做好了准备。还记得有个公司叫 九城吗&#x…

创建自己的函数库

创建自己的函数库前言一、什么是STM32标准函数库1.定义&#xff1a;2.作用&#xff1a;3.对比&#xff1a;二、构建库函数1.修改寄存器地址封装2.定义访问的结构体指针和引脚3.创建封装函数3.1创建拉低引脚函数3.2创建引脚初始化函数总结前言 回顾一下&#xff0c;前面点亮led…

堆 (带图详解)

文章目录1.堆的基本概念1. 概念2.性质1.必须为完全二叉树2.满足大堆/小堆成立的条件3.存储方式1.逻辑结构2.物理结构4. 孩子与父亲之间下标的关系2.堆的基本实现1.push——插入1.代码2. 情况分析情况1情况23. 向上调整算法1.过程分析2. 临界条件的判断2. pop—— 删除1.代码2. …

redis哨兵系列1

需要配合源码一起康~ 9.1 哨兵基本概念 官网手册yyds&#xff1a;https://redis.io/docs/manual/sentinel/ redis主从模式&#xff0c;如果主挂了&#xff0c;需要人工将从节点提升为主节点&#xff0c;通知应用修改主节点的地址。不是很友好&#xff0c;so Redis 2.8之后开…

C# async / await 用法

目录 一、简介 二、异步等待返回结果 三、异步方法返回类型 四、await foreach 五、Task.Delay 结束 一、简介 await 运算符暂停对其所属的 async 方法的求值&#xff0c;直到其操作数表示的异步操作完成。 异步操作完成后&#xff0c;await 运算符将返回操作的结果&…

使用STM32CubeMX实现按下按键,电平反转

需提前学习&#xff1a;使用STM32CubeMX实现LED闪烁 目录 原理图分析 按键部分原理图分析 LED部分原理图分析 STM32CubeMX配置 关于STM32CubeMXSYS的Debug忘记配置Serial Wire处理办法 GPIO配置 LED的GPIO配置 KEY1配置 关于PA0后面这个WKUP是什么&#xff1f; 那么啥…

利用ogg微服务版将oracle同步到kafka

ogg微服务版可以再界面上配置抽取、复制进程&#xff0c;不必进入到shell中进行配置&#xff0c;并且图形化界面可以看到更多信息。 系统架构 源端安装ogg for oracle 19C , 目标端安装ogg for bigdata 21C kafka 2.2 数据库&#xff1a;19C 所有软件安装在同台服务器上&#…

理解Linux32位机器下虚拟地址到物理地址的转化

文章目录前言一、基本概念介绍二、虚拟地址到物理地址的转化过程总结前言 简要介绍LINUX32位系统下虚拟地址到物理地址的转化过程。 一、基本概念介绍 在32位机器下&#xff0c;IO的基本单位是块&#xff08;块&#xff1a;4kb),在程序编译成可执行程序时也划分好了以4kb为单…