首页 > 其他分享 >数据结构(6):串(上)

数据结构(6):串(上)

时间:2022-12-01 11:05:00浏览次数:46  
标签:字符 ch return int len length 数据结构




数据结构(6):串(上)_子串



字符串简称串,计算机上非数值处理的对象基本都是字符串数据。我们常见的信息检索系统(如搜索引擎)、文本编辑程序(如 Word)、问答系统、自然语言翻译系统等,都是以字符串数据作为处理对象的。本文详细介绍字符串的存储结构及相应的操作。





串的定义


(string)是由零个或多个字符组成的有限序列。一般记为

数据结构(6):串(上)_基本操作_02

其中,S 是串名,单引号括起来的字符序列是串的值;串中字符的个数 n 称为串的长度。n=0 时的串称为空串(用∅表示)。

串中任意连续个字符组成的子序列称为该串的子串,包含子串的串相应地称为主串。某个字符在串中的序号称为该字符在串中的位置。子串在主串中的位置以子串的第一个字符在主串中的位置来表示。当两个串的长度相等且每个对应位置的字符都相等时,称这两个串是相等的。

例如,有串 A='China Beijing',B='Beijing',C='China',则它们的长度分别为 13,7 和 5。B 和 C 是 A 的子串,B 在 A 中的位置是 7,C 在 A 中的位置是 1。

需要注意的是,由一个或多个空格(空格是特殊字符)组成的串称为空格串(注意,空格串不是空串),其长度为串中空格字符的个数。

串的逻辑结构和线性表极为相似,区别仅在于串中的数据对象限定为字符集。在基本操作上,串和线性表有很大差别。线性表的基本操作主要以单个元素作为操作对象,如查找、插入或删除某个元素等;而串的基本操作通常以子串作为操作对象,如查找、插入或删除一个子串等。 


串的存储结构


大家看完定义就会明白,这不就是 Python 中的 str 数据类型吗?确实如此,所以我就不用Python 的 str 套壳实现一个串了,依旧换成 C/C++ 来实现串。



定长顺序存储表示



类似于线性表的顺序存储结构,用一组地址连续的存储单元存储串值的字符序列。在串的定长顺序存储结构中,为每个串变量分配一个固定长度的存储区,即定长数组。

#define MAXLEN 255//预定义串中最大串长为 255
class SString
{
private:
char ch[MAXLEN];//为每个分量存储一个字符
int length;//串的实际长度
};

串的实际长度只能小于等于 MAXLEN,超过预定义长度的串值会被舍去,称为截断。串长有两种表示方法:一是如上述定义那样,用一个额外的变量 len 来存放串的长度;二是在串值后面加一个不计入串长的结束标记字符“\0”,此时串长为隐含值。

在一些串的操作(如插入、联接等)中,若串值序列的长度超过上界 MAXLEN,约定用“截断”法处理,要克服这种弊端,只能不限定串长的最大长度,即采用动态分配的方式。


堆分配存储表示



堆分配存储表示仍然以一组地址连续的存储单元存放串值的字符序列,但它们的存储空间是在程序执行过程中动态分配得到的。

class HString
{
private:
char* ch;//按串长分配存储区,ch 指向串的基地址
int length;//串的长度
};

在 C 语言中,存在一个称之为“堆”的自由存储区,并用 malloc()和 free()函数来完成动态存储管理。利用 malloc()为每个新产生的串分配一块实际串长所需的存储空间,若分配成功,则返回一个指向起始地址的指针,作为串的基地址,这个串由 ch 指针来表示 ;若分配失败,则返回 NULL。已分配的空间可用 free()释放掉。

上述两种存储表示通常为高级程序设计语言所采用。块链存储表示仅作简单介绍。



块链存储表示



类似于线性表的链式存储结构,也可以采用链表方式存储串值。由于串的特殊性(每个元素只有一个字符),在具体实现时,每个结点即可以存放一个字符,也可以存放多个字符。每个结点称为,整个链表称为块链结构


串的基本操作


串的基本操作一共有 10 个:赋值操作、复制操作、判空操作、比较操作、求串长、求子串、串联接、定位操作、清空操作和销毁串。

我在这里基于堆分配存储表示来实现这 10 个基本操作。



赋值操作



void StrAssign(const char* chars)
{
length = 0;
while (chars[length])
length++;
ch = new char[length + 1];
if (!ch)
return;
for (int i = 0; i < length; i++)
ch[i] = chars[i];
ch[length] = 0;
}



复制操作


void StrCopy(HString& T)
{
T.StrAssign(ch);
}



判空操作



bool StrEmpty()
{
return length ? false : true;
}



比较操作



int StrCompare(HString T)
{
int len = length < T.length ? length : T.length;
for (int i = 0; i < len; i++)
{
if (ch[i] < T.ch[i])
return-1;
else if (ch[i] > T.ch[i])
return 1;
}
if (ch[len])
return 1;
if (T.ch[len])
return-1;
return 0;
}



求串长



int StrLength()
{
return length;
}


求子串



void SubString(HString& Sub, int pos, int len)
{
if (pos + len - 1 > length)
return;
Sub.length = len;
Sub.ch = new char[len + 1];
if (!Sub.ch)
return;
for (int i = pos - 1, j = 0; j < len; i++, j++)
Sub.ch[j] = ch[i];
Sub.ch[len] = 0;
}


串联接



void ConCat(HString S1, HString S2)
{
length = S1.length + S2.length;
ch = new char[length + 1];
if (!ch)
return;
int i = 0;
for (; i < S1.length; i++)
ch[i] = S1.ch[i];
for (; i < length; i++)
ch[i] = S2.ch[i - S1.length];
ch[length] = 0;
}



定位操作



int Index(HString T)
{
int i = 1;
HString sub;
while (i <= length - T.length + 1)
{
SubString(sub, i, T.length);
if (sub.StrCompare(T) != 0)
++i;
else
return i;//返回子串在主串中的位置
}
return 0;//S 中不存在与 T 相等的子串
}



清空操作



void ClearString()
{
ch = new char[1];
ch[0] = 0;
length = 0;
}



销毁串



~HString()
{
delete[]ch;
ch = 0;
}


总结


关于串的定义和基本操作就说到这里,下一回我们来看一个有关于串的应用:模式匹配!

当然,我从今年开始已经入驻 B 站了!下面给出 B 站账号:新时代的运筹帷幄,喜欢的可以关注一下,看完视频不要忘记一键三连啊!

今天的文章有不懂的可以后台回复“加群”,备注:Python 机器学习算法说书人,不备注可是会被拒绝的哦~!



数据结构(6):串(上)_基本操作_03





标签:字符,ch,return,int,len,length,数据结构
From: https://blog.51cto.com/u_15829940/5901374

相关文章

  • 数据结构(4):队列(上)
    上回说到,栈常见的三个应用:括号匹配、表达式求值以及递归。这一会我们来看一看另一个操作受限的线性表:队列!队列的基本概念队列的定义队列(Queue)简称队,也是一种操作受限的线性......
  • 数据结构(3):栈(上)
    上一回,我讲了一下链表的应用:一元多项式,这一回,我们来看到一个全新的数据结构:栈!栈的基本概念栈的定义栈(Stack)是一种只允许在一端进行插入或删除操作的线性表。首先栈是一种线......
  • 数据结构入门级-串
    1、串的概念字符串简称串,是一种特殊的线性表,它的数据元素仅由一个字符组成。2、串的定义串(String)是由零个或多个字符组成的有限序列,又称字符串。   其中s是串......
  • 【数据结构】笛卡尔树
    把一个数组的元素,从左到右插入笛卡尔树,可以用栈O(n)地构建出来。笛卡尔树上的节点满足堆的性质(小根堆就是一个节点小于其两个子节点的权值)。所以用这个方式扫描出的笛卡尔......
  • 常用代码模板2——数据结构
    常用代码模板2——数据结构单链表//head存储链表头节点的下标,e[]存储节点的值,ne[]存储节点的next指针,idx表示当前可以用的最新的点的下标inthead,e[N],ne[N],idx;......
  • 【数据结构】广义表
    广义表参考:广义表的存储结构详解(包含2种存储方案)(biancheng.net)(10条消息)【实例】复制广义表_Chaim16的博客-CSDN博客广义表的定义线性表线性表指的是n≥0个......
  • PYTHON 数据结构 - 列表
    1.1列表列表类似元组:可以存放多个元素(可不同类型)有顺序可重复列表是可变的,可添加,删除,排序元素1.2列表的创建#列表=[元素1,元素2,...]a=[1,2,3,4]a=[]......
  • 数据结构实验之栈与队列二:一般算术表达式转换成后缀式 sdut-oj
    #include<stdio.h>#include<stdlib.h>#defineSTACK_INIT_SIZE100#defineSTACKINCREMENT100typedefstruct{  char*base;  ......
  • 数据结构实验之栈与队列四:括号匹配 sdut-oj
    #include<stdio.h>#include<stdlib.h>#defineSTACK_INIT_SIZE100#defineSTACKINCREMENT10typedefstruct{  char*base;  ......
  • 「Java数据结构」- 栈和队列
    栈的认识========栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。压栈:栈的插入操作叫做进栈/......