4.2 串的表示和实现

        如果在程序设计语言中,串只是作为输入或输出变量存在,那么只需存储此串的值,即字符序列即可。在多数非数值处理的程序中,串也可以以变量的形式出现。

串有三种机内表示方法,分别如下:

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;

设尾指针的目的是为了串联接时的操作方便,但应注意处理串联接时第一个串尾的无效字符。















下载好代码后直接在linux环境下减压,make之后即可产生可执行代码,压缩文件中已经包含了可执行代码。 通过分配存储结构来实现的以下功能: //生成一个值等于常量chars的string int StrAssign(HString *str,char *chars); //返回string的长度 int StrLength(HString str); //比较两个的大小,如果str1 > str2,返回值>0,如果相等,返回0,如果str1 < str2,返回值<0 int StrCompare(HString str1,HString str2); //清空,释放所占用的空间 int ClearString(HString *str); //返回Str1和Str2联合而成的 HString Concat(HString str1,HString str2); //返回str的第pos个字符之后的长度为len的子 HString SubString(HString str,int pos,int len); //显示字符 int StrTrave(HString str); //-----------------------附加操作函数-------------------------- //以下操作可由基本操作来实现 //str1复制得到str2 int StrCopy(HString str1,HString *str2); //str为空,返回1,否则返回0 int StrEmpty(HString str); //如果主str中存在和substr相等的子,则返回子在主中pos个字符之后第一次出现的位置 ,运用了KMP算法 int Index(HString str,HString substr,int pos); //Index中包括了一个静态函数get_next(),这个函数可以得到字符的最简匹配值(kmp算法中字符匹配失败后的下一个最佳匹配值) //用字符Tstr替换主str中出现的所有与substr相等的子 int StrReplace(HString **str,HString substr,HString Tstr); //在str的第pos个字符之后插入substr int StrInsert(HString *str,HString substr,int pos); //从str的第pos个字符起删除len个字符 int StrDelete(HString **str,int pos,int len); //销毁现有str int StrDestory(HString *str);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值