如果在程序设计语言中,串只是作为输入或输出变量存在,那么只需存储此串的值,即字符序列即可。在多数非数值处理的程序中,串也可以以变量的形式出现。
串有三种机内表示方法,分别如下:
4.2.1 定长顺序存储表示
类似于线性表的顺序存储结构,用一组地址连续的存储单元存储串值的字符序列。按照预定义的串长,为每个串变量分配一个固定长度的存储空间,则可用定长数组描述如下
# define MAXSTRLEN 255
typedef unsigned char SString[MAXSTRLEN + 1] //这里定义的串,下面函数会调用到;
串的长度可以在预定义的范围内随意,超过预定义长度的串值则被舍去,称之为“截断”;对串长有两种表示方法:一种是如上描述的那样,以下标为0的数组分量存储串的实际长度,如PASCAL语言中的类型串采用这种表示方法;二是在串值结束处加一个不计入串长的串结束标志符,如在C语言中用“\0”表示串值的结束,此时的串长为隐含值,显然不方便进行某些串操作。
求子串:与堆分配存储的求子串对比来分析
Status SubString(SString &sub,SString S,int pos,int len)
{
if(pos < 1 || pos > S[0] || len < 0 || len > S[0] - pos + 1) return ERROR;
sub[1...len] = S[pos...pos + len -1];
sub[0] = len;
return OK;
}

4.2.2 堆分配存储表示
这种存储表示的特点是,仍然以一组地址连续的存储空间存储串字符序列,但是不同的是这个存储单元是随机分配的,就是在程序执行过程中动态分配的,
不同的地方:例如在C语言中的函数malloc()和free()来管理。
用malloc分配成功,则返回一个指针(指向起始地址的),作为串的基址,同时为了以后处理方便,约定串长也作为存储结构的一部分。
typedef struct{
char *ch; //若为非空,则按串长分配存储单元,否则ch为NULL;
int length;//串长;
}HString;//这里的串定义下面就能调用;
例如:求子串与串的顺序存储结构的区别,就是malloc的区别;
Status SubString(HString &sub,HString S,int pos,int len)
{
if(pos < 0 || pos > S.length || len < 0 || len > S.length - pos + 1) return ERROR;
if(sub.ch) free(sub.ch);
if(!len)
{
sub.ch = NULL;
sub.length = 0;
}
else
{
(sub.ch = (char *)malloc(len*sizeof(char))
sub.ch[0...len -1] = S.ch[pos -1...pos + len -2];
sub.length = len;
}
return OK;
}
如串插入StrInsert(&S,pos,T)操作是重新为串S分配大小为串S和串T长度之和的存储单元,然后进行串值复制。
Status StrInsert(&S,pos,T)
{
if(pos < 1 || pos >S.length + 1) return ERROR;
if(T.length) //T非空;
{
if(!(S.ch = (char *)remalloc(S.ch,(S.length + T.length)*sizeof(char)))) exit(OVERFLOW);
for(i = S.length - 1;i > pos -1; - -i)
S.ch[i + T.length] = S.ch[i]; //注意这里是数组,也就是为插入T而腾出位置;
S.ch[pos - 1...pos + T.length] = T.ch[0...T.length -1];//这里是从串S的pos位置开始插入T,假如S长10那么pos必须是11,而数组下标表示序列的特殊性
//所以用(pos - 1)位置开始插入到数组中。
S.length += T.length;
}
return OK;
}
由于对分配存储结构的串既有顺序存储结构的特点,处理方便,又对串长没有任何限制,更显灵活,因此在串处理程序中经常被使用。
4.2.3 串的块链存储表示
和线性表的链式存储结构相类似,也可采用链表方式存储串值。由于串结构的特殊性——结构中的每个数据元素是一个字符,采用链表存储串值时,存在一个结点大小的问题,即每个结点可以存放一个字符,也可以存放多个字符。
为了便于进行串的操作,当以链表存储串值时,除头指针还可以附设一个尾指针指示链表中的最后一个结点,并给出当前串的长度。称如此定义的串存储结构为块链结构,说明如下:
//------------串的块链存储表示-------------------------
#define CHUNKSIZE 100 //可由用户定义的块大小
typedef struct Chunk{
char ch[CHUNKSIZE];
struct Chunk *next;
}Chunk;
typedef struct{
Chunk *head,*tail; //串的头尾指针
int curlen; //串的当前长度
}LString;
设尾指针的目的是为了串联接时的操作方便,但应注意处理串联接时第一个串尾的无效字符。