文章目录
前言
串(字符串)是一种特殊的线性表,它的数据元素仅有一个字符组成。一般情况下处理的非数值型数据对象经常是字符串数据,例如在事务处理中,顾客的姓名、地址、货物产地等,一般都作为字符串处理。通常以“串的整体”作为处理对象。
一、串的定义
串的定义:
串(string)是由零个或多个任意字符组成的字符序列。
通常记为:s="a1,a2,a3,...,an"
- s是串的名称,用双引号括起来的是串的值。
- 串中字符的数目n称为串的长度。
- 零个字符的串称为空串(null string),串的长度为0,用∅表示。
空格串:由一个或多个空格组成的串。
子串与主串:串中任意连续的字符组成的子序列称为该串的子串。包含子串的串称为主串。
子串的位置 :子串的第一个字符在主串中的序号。
串相等:两个串的长度相等且对应位置的字符相同。
二、串的存储结构
1.串的顺序存储结构
串的顺序存储结构是用一组地址连续的存储单元来存储字符序列的。按照预定义的大小,为每个定义的串变量分配一个固定长度的存储区。一般用定长数组来定义。
串的实际长度可以在预定义长度的范围内随意,超出预定义长度的串值则会被舍弃,称之为“截断”。
2.串的定长顺序存储及运算
/*定义方法1*/
#define MAXSIZE 255
typedef char SString[MAXSIZE+1];//0号单元存放串的长度
//定义方法2
/*
typedef struct
{
char data[MAXSIZE];
int curlen;
}SeqString;
SeqString s;
*/
/*串连接*/
/*
假设S1,S2,T都是SString型的串变量,串T是由串S1联结串S2得到。
基于S1和S2长度的不同情况,串T可能有3种情况:
(1)S1[0]+S2[0]=<MAXSIZE
(2)S1[0]<MAXSIZE,S1[0]+S2[0]>MAXSIZE,则S2被部分截断
(3)S1[0]>=MAXSIZE,则只包含S1
*/
int Concat(SString &T,SString S1,SString S2)
{
int flag=1;//标志是否截断,1表示没截断,0表示截断
int j,k;
j=1,k=1;
if(S1[0]+S2[0]=<MAXSIZE){
while(S1[j]!='\0'){
T[k++]=S1[j++];
}
j=1;
while(S2[j]!='\0'){
T[k++]=S2[j++];
}
T[0]=S1[0]+S2[0];
}
else if(S1[0]<MAXSIZE){
while(S1[j]!='\0'){
T[k++]=S1[j++];
}
j=1;
while(k<MAXSIZE){
T[k++]=S2[j++];
}
T[0]=MAXSIZE;
flag=0;
}
else{
while(S1[j]!='\0'){
T[k++]=S1[j++];
}
T[0]=MAXSIZE;
flag=0;
}
return flag;
}
3.串的块链存储结构
对于串的链式存储结构,与线性表相似,但由于串结构的特殊性,结构中的每个元素数据是一个字符,如果也简单的应用链表存储串值,一个结点对应一个字符,就会存在很大的空间浪费。因此可以一个结点存放一个字符,也可以考虑存放多个字符,最后一个结点若是没有占满,可以用“#” 或其他的非串值字符补全。
#define CHUNKSIZE 80 //定义块的大小
typedef struct chunk{
char ch[CHUNKSIZE];
struct chunk *next;
}chunk;
typedef struct{
chunk *head,*tail;//串的头指针和尾指针
int curlen; //串的当前长度
}LString;
一般情况下,对串进行操作时,只需要从头到尾顺序扫描即可,对串值不必建立双向链表。
设尾指针的目的是为了方便进行联结操作,但应注意联结时需要处理第一个串尾的无效字符。
存储密度: