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

news2025/7/9 1:16:52

串基本概念:串是由零个或者多个字符组成的有限序列,一半记作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;
	}
	else
	return 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];
		}
	else
	S->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;
	else
	return 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;
		}
		else
		k = 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.coloradmin.cn/o/18394.html

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

相关文章

[附源码]计算机毕业设计JAVA红河旅游信息服务系统

[附源码]计算机毕业设计JAVA红河旅游信息服务系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM my…

Swin Transformer代码实现部分细节重点

swin transformer 1.patch-merging部分 代码&#xff1a;【amazing】 x0 x[:, 0::2, 0::2, :] # [B, H/2, W/2, C] 对应图片所有 1 的位置x1 x[:, 1::2, 0::2, :] # [B, H/2, W/2, C] 对应图片所有 3 的位置x2 x[:, 0::2, 1::2, :] # [B, H/2, W/2, C] 对应图片所有…

pve独显直连

目录折腾初步工作安装配置源去除订阅提示安装vim开启iommu屏蔽显卡驱动创建虚拟机体验折腾 买了个新笔记本&#xff0c;老的笔记本也没啥用了&#xff0c;挂二手平台也出不了多少钱。就想着自己折腾的新东西。之前有个PVE虚拟机感觉很不错&#xff0c;现在尝试一下怎么使用 初…

用HTML+CSS6音乐吧 7页

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 音乐网页设计 | 仿网易云音乐 | 各大音乐官网网页 | 明星音乐演唱会主题 | 爵士乐音乐 | 民族音乐 | 等网站的设计与制作 | HTML期末大学生网页设计作…

[附源码]SSM计算机毕业设计在线购物系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

英文版通信原理学习通题库

1、 能量信号的功率趋于&#xff08; &#xff09; A、 无穷 B、 0 C、 非零值 答案&#xff1a; B 2、周期信号的频谱是&#xff08; &#xff09; A、 连续谱 B、 离散谱 C、 既有连续谱&#xff0c;又有离散谱 答案&#xff1a; B 3、 信号的频谱如所示&…

第十三届蓝桥杯c++b组-积木画

题目描述 小明最近迷上了积木画&#xff0c;有这么两种类型的积木&#xff0c;分别为 I 型&#xff08;大小为 2 个单位面积&#xff09;和 L 型&#xff08;大小为 3 个单位面积&#xff09;&#xff1a; 同时&#xff0c;小明有一块面积大小为 2 N 的画布&#xff0c;画布…

云原生路由架构探索

以部署场景为中心的网络架构 网络技术的发展一直以来是以部署场景为中心&#xff0c;很多设备厂商也很自然的分成运营商 、数据中心 、企业网 、终端 等各个事业部。很多网络技术也是为了解决某个特定场景的问题而提出的。当然在这个过程中也相互借鉴&#xff0c;例如将MPLS V…

基于java+ssm教学质量评价系统(学生评教)-计算机毕业设计

项目介绍 教学质量是高等教育的生命线&#xff0c;提高教学质量是提高教育质量的前提&#xff0c;因此也是学校的首要任务。学生评价教师作为教师评教的重要途径&#xff0c;正在被很多学校采纳。学生评价教师体现了学校管理者对学生权利的尊重&#xff0c;以及促进师生沟通的…

Linux常见命令与Java环境部署

⭐️前言⭐️ &#x1f349;博客主页&#xff1a; &#x1f341;【如风暖阳】&#x1f341; &#x1f349;精品Java专栏【JavaSE】、【备战蓝桥】、【JavaEE初阶】、【MySQL】、【数据结构】 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&…

ijkplayer基于rtsp直播延时的深度优化

现在ijkPlayer是许多播放器、直播平台的首选&#xff0c;相信很多开发者都接触过ijkPlayer&#xff0c;无论是Android工程师还是iOS工程师。本文主要是总结&#xff0c;也是与大家探讨RTSP直播的延时优化。 目录 一、修改编译脚本支持RTSP 二、修改播放器的option参数 三、…

WEB基础

互联网简介 互联网是世界上最大的计算机网络 互联网被称为网络的网络 万维网是互联网中的一个子网 WWW包含分散在世界范围内的众多Web 服务器&#xff08;World Wide Web&#xff09;WEB web即全球广域网World Wide Web&#xff0c;也称万维网&#xff0c;是一种基于超文本和HT…

基于ssm+mysql+jsp作业管理(在线学习)系统

基于ssmmysqljsp作业管理&#xff08;在线学习&#xff09;系统一、系统介绍二、功能展示1.用户登陆2.用户注册3.在线学习&#xff08;评论&#xff09;--学生4.任务列表--学生5.我的作业--学生6.个人中心7.发布课程--老师8.发布任务--老师9.评阅作业10.后台管理--管理员一、系…

RabbitMQ初步到精通-第五章-RabbitMQ之消息防丢失

目录 第五章-RabbitMQ之消息防丢失 1.消息是如何丢的 ​编辑 2.如何控制消息丢失 2.1 生产者发送消息到Broker过程 2.2 Broker内部过程 2.2.1 Exchange发送至queue过程-Return机制 2.2.2 queue存储过程 2.3 消费者消费过程-消费端确认 3.最佳实践 第五章-RabbitMQ之消息…

养老服务系统设计与实现-计算机毕业设计源码+LW文档

基于SSM的养老服务系统设计与实现 摘 要 本养老服务系统就是建立在充分利用现在完善科技技术这个理念基础之上&#xff0c;并使用IT技术进行对养老服务的管理&#xff0c;从而保证系统得到充分利用&#xff0c;可以实现养老服务的在线管理&#xff0c;这样保证了资源共享效率的…

牛客刷题记录(常见笔试题)

目录 一、Map的应用篇 乒 乓球筐 简单的错误记录 二、动态规划篇 计算字符串的编辑距离 年终奖 最长不含重复字符的子字符串 合唱团 三、数组篇 顺时针打印矩阵 一、Map的应用篇 乒 乓球筐 题目地址&#xff1a;乒乓球筐 小白代码 import java.util.*;// 注意类名必…

一次就能释放大量Mac内存空间的方法,你用过哪种?

清理Mac内存空间对Mac的运行速度有着非常大的好处&#xff0c;所以合理释放Mac内存空间是广大用户常做的一件事。那么小编整理了一些能够一次性大量释放Mac内存空间的方法&#xff0c;大家常用的是哪一种呢&#xff1f;欢迎一起交流哦~以下&#xff1a; 一、清理MAC缓存&#x…

微信小程序|从零动手实现俄罗斯方块

&#x1f4cc;个人主页&#xff1a;个人主页 ​&#x1f9c0; 推荐专栏&#xff1a;小程序开发成神之路 --【这是一个为想要入门和进阶小程序开发专门开启的精品专栏&#xff01;从个人到商业的全套开发教程&#xff0c;实打实的干货分享&#xff0c;确定不来看看&#xff1f; …

[Linux]----进程间通信之管道通信

文章目录前言一、进程间通信目的二、进程间通信发展三、进程间通信分类四、管道1. 匿名管道2. 管道内核代码3. 站在文件描述符角度-深度理解管道4. 站在内核角度-管道本质5. 管道的特征总结五、命名管道1. 创建命名管道总结前言 首先我基于通信背景来带大家了解进程间通讯&…

HTTP协议详细总结

目录 1.HTTP协议是什么? 2.什么叫做应用层协议 3.HTTP协议的工作流程 4.HTTP报文格式 请求报文: 响应报文: 5.URL 6.方法的认识 1.GET 2.POST 3.GET和POST的区别 4.其他方法 7.报头的认识 用户登陆过程: 8.状态码的认识 9.HTTPS 9.1HTTPS是什么? 9.2HTTPS的…