数据结构~11.串
本文是上一篇文章的后续,详情点击该链接~
串的基本定义
串是由零个或者多个字符组成的有序序列。串中字符的个数称为串的长度,含有零个元素的串叫空串。
//这就好比一个名为str的串
char str[] = "today is greate day";
串中任意连续的字符组成的子序列称为该串的子串,包含子串的串称为主串,某个字符在串中的序号称为这个字符的位置。通常用子串第一个字符作为子串在主串中的位置。要注意,空格也是串字符集合中的一个元素,由一个或者多个空格组成的串称为空格串(注意:空格串不是空串)
串的逻辑和线性表类似,串限定了元素为字符的线性表。从操作集上讲,串和线性表有很大的区别,线性表的操作主要针对表内的某一个元素,而串操作主要针对串内的一个子串
串的存储结构
一般不采用刚才的那种方式来定义并初始化一个串。原因是仅仅以'\0'作为串结束的标记在求串长的时候需要扫描整个串,时间复杂度为O(n)。不如额外来定义一个变量,专门来存储串的长度,这样一来求串长的时间复杂度为 O(1)
顺序存储表示结构体定义如下
#define MAXSIZE 100
typedef struct {
char str[MAXSIZE + 1]; //MAX + 1 是为了多出一个 \0 作为结束标记
int length;
}Str;
动态分配存储表示
在程序执行的过程根据需要动态分配
typedef struct {
char *ch; //指向动态分配存储区首地址的字符指针
int length; //串的长度
}Str;
这种存储方式在使用时,需要用函数malloc()来分配一个长度为length,类型为char的存储空间,分配的空间可以用函数free()释放掉。用函数malloc()分配存储的空间如果成功,则返回一个指向起始地址的指针,作为串的基地址,这个地址由ch指针来指向。如果分配失败,则返回NULL。
动态分配存储比顺序存储更加灵活,因此在串处理应用程序中,更为常用。
串的基本操作
赋值操作
与普通变量赋值操作不同,串的赋值操作不能直接用=来表示,因为串是一个数组,必须对数组中的每个元素进行逐一赋值。操作串的赋值操作可以用strassign()实现。其功能是将一个常量字符串赋值给str。成功返回1,失败返回0
int strassign(Str &str,char *ch) {
int len = 0,i;
char* c = ch; //将ch赋给c,这样操作c时候,就不会破坏原来的ch
//求串c的长度
while (*c) {
len++;
c++;
}
if (len == 0) {