zoukankan      html  css  js  c++  java
  • 串的动态存储分配

          串:由零个或者多个字符组成的有限序列。零个字符的串称为空串,和空格串【一个或多个空格诸城的串】有区别,请注意比较。在串的抽象数据类型中,有五个操作组成最小操作子集,分别是串赋值StrAssign,串比较StrCompare,求串长StrLength ,串联接Concat,求子串SubString。现以串的动态存储结构为例,将5个基本操作实现如下:

    具体介绍详见注释。

      1 /**
      2 在串的抽象数据类型的13中操作中:串赋值StrAssign,串比较StrCompare,求串长StrLength
      3 串连接Concat,求子串SubString构成串类型的最小操作子集
      4 
      5 串有三种表示方法:
      6     定长顺序表示
      7     堆分配存储表示
      8     块链存储表示
      9 */
     10 
     11 //主要介绍动态分配:对分配储存表示
     12 //仍然以一组地址连续的存储单元来存放串值字符序列,但他们的存储空间是在程序执行的过程中动态分配的。
     13 //C语言中有一个称之为“堆”自由存储区,并有malloc和free函数来管理
     14 #include <stdio.h>
     15 #include <stdlib.h>
     16 #include <string.h>
     17 //------------------串的堆分配存储结构-----------------
     18 typedef struct
     19 {
     20     char *ch;  //若是非空串,则按串长分配存储区,否则ch为NULL
     21     int length;//串长度
     22 } HString;
     23 
     24 //---------------------串插入操作-----------------------
     25 void StrInsert(HString &S,int pos,HString T)
     26 {
     27     //1<=pos<=StrLength(S)+1,在串S的第pos个字符之前插入串T
     28     if ( pos<1 || pos>S.length+1 )
     29     {
     30         printf("插入位置有误,请确认后重新输入
    ");
     31         getchar();
     32         exit(1);
     33     }
     34     if (T.length)//T非空,则重新分配空间,插入T
     35     {
     36         if(!(S.ch = (char*)realloc(S.ch,(S.length+T.length)*sizeof(char))))
     37         {
     38             printf("空间重新分配有误,任意键退出!
    ");
     39             getchar();
     40             exit(1);
     41         }
     42         for (int i = S.length-1 ; i >= pos-1; --i)
     43         {
     44             /* 为插入T腾出位置 ,从最后一个全体向后挪动T.length个长度*/
     45             S.ch[i+T.length] = S.ch[i];
     46         }
     47         for (int i = 0 ; i < T.length; ++i)
     48         {
     49             /* 将T中的字符插入到S中 */
     50             S.ch[i+pos-1] = T.ch[i];
     51         }
     52         S.length +=T.length;
     53     }
     54 }
     55 //-------------------串的五种基本操作-------------------
     56 void StrAssign(HString &T,char *chars)
     57 {
     58     //生成一个其值等于串常量chars的串T
     59 
     60     if(T.ch)
     61     {
     62         /* 释放T原有空间 */
     63         free(T.ch);
     64     }
     65     int count = 0;//计算字符串长度;
     66     char *c = NULL;
     67 
     68     for(count = 0,c = chars; *c ; ++count,++c);//求chars的长度count
     69     if (!count)
     70     {
     71         /* 空串 */
     72         T.ch = NULL;
     73         T.length = 0;
     74     }
     75     else
     76     {
     77         if (!(T.ch = (char *)malloc(count * sizeof(char))))
     78         {
     79             printf("分配存储空间有误!
    ");
     80             exit(1);
     81         }
     82         for (int i = 0; i < count; ++i)
     83         {
     84             T.ch[i] = chars[i];
     85         }
     86         T.length = count;
     87     }
     88 
     89 }
     90 
     91 //---------------------------求串长度-----------------------
     92 int StrLength(HString S)
     93 {
     94     //返回S的元素个数,称为串的长度
     95     return S.length;
     96 }
     97 
     98 //--------------------------串比较函数------------------------
     99 int StrCompare(HString S,HString T)
    100 {
    101     //若S>T,则返回值大于0;若S<T,则返回值<0;若S=T,则返回值=0
    102     for (int i = 0; i < S.length && i < T.length; ++i)
    103     {
    104         if (S.ch[i] != T.ch[i])
    105         {
    106             return S.ch[i] - T.ch[i];
    107         }
    108     }
    109     return S.length - T.length;
    110 }
    111 
    112 //--------------------------串清除函数------------------------
    113 void ClearString(HString &S)
    114 {
    115     //将串S清除为空串
    116     if (S.ch)
    117     {
    118         free(S.ch);
    119         S.length = 0;
    120     }
    121     S.length = 0;
    122 }
    123 
    124 //--------------------------串联接函数------------------------
    125 void Concat(HString &T,HString S1,HString S2)
    126 {
    127     //用串T返回串S1和串S2联接给成的新串
    128     if (!T.ch)
    129     {
    130         free(T.ch);//释放旧空间
    131     }
    132     if (!(T.ch = (char*)malloc((S1.length+S2.length)*sizeof(char))))
    133     {
    134         printf("分配存储空间有误!
    ");
    135         exit(1);
    136     }
    137     //将两个串联接起来
    138     for (int i = 0; i < S1.length; ++i)
    139     {
    140         T.ch[i] = S1.ch[i];
    141     }
    142     T.length = S1.length + S2.length;
    143     for (int i = 0; i < S2.length; ++i)
    144     {
    145         T.ch[i+S1.length] = S2.ch[i];
    146     }
    147 }
    148 
    149 //----------------------------求子串函数----------------------------
    150 void SubString(HString &Sub,HString S,int pos,int len)
    151 {
    152     //用Sub返回串S的第pos个字符起长度为len的子串
    153     //其中,1<=pos<=StrLength(S)且  0<=len<=StrLength(S)-pos+1
    154     if (pos<1 || pos>S.length || len<0 || len>S.length-pos+1)
    155     {
    156         printf("输入的求子串位置有误,请确认后重新输入!
    ");
    157     }
    158     if (Sub.ch)
    159     {
    160         free(Sub.ch); //释放旧空间
    161     }
    162     if(!len)
    163     {
    164         //空子串
    165         Sub.ch = NULL;
    166         Sub.length = 0;
    167 
    168     }
    169     else
    170     {
    171         Sub.ch = (char*)malloc(len * sizeof(char));
    172         for (int i = 0; i < len; ++i)
    173         {
    174             Sub.ch[i] = S.ch[pos+i-1];
    175         }
    176         Sub.length = len;
    177 
    178     }
    179 }
    180 //--------------------------输出串内容---------------------------
    181 void PrintStr(HString S)
    182 {
    183     if(S.ch)
    184     {
    185         for(int i=0; i<S.length; ++i)
    186         {
    187             printf("%c",S.ch[i]);
    188         }
    189         printf("
    ");
    190     }
    191     else
    192     {
    193         printf("该串是空串!
    ");
    194     }
    195 }
    196 
    197 int main(int argc, char const *argv[])
    198 {
    199     char *c1 = "Hello,this is a test for String";
    200     char *c2 = "I'm string2";
    201     HString s1,s2,s3;
    202     //先将s1,s2,s3置为空串
    203     s1.ch = NULL;
    204     s1.length = 0;
    205     s2.ch = NULL;
    206     s2.length = 0;
    207     s3.ch = NULL;
    208     s3.length = 0;
    209     //测试串赋值
    210     StrAssign(s1,c1);
    211     StrAssign(s2,c2);
    212     printf("两个串赋值之后:
    ");
    213     PrintStr(s1);
    214     PrintStr(s2);
    215     //测试串比较
    216     printf("%d
    ",StrCompare(s1,s2));
    217     //测试串连接
    218     Concat(s3,s1,s2);
    219     PrintStr(s3);
    220     //测试求子串
    221     SubString(s3,s1,1,5);
    222     printf("子串:");
    223     PrintStr(s3);
    224     //测试清空串
    225     ClearString(s3);
    226     printf("清空该串后,输出结果为:");
    227     PrintStr(s3);//无输出结果(串的内容为空),串长度为0
    228     return 0;
    229 }
  • 相关阅读:
    ES6解构赋值
    ES6中的Symbol类型
    两个列表合并成字典
    python关于列表转为字典的两个小方法
    break、continue和return的使用
    进度条的实现
    md5加密
    dict字典方法
    用户相关的文件、解析以及命令的使用
    linux的根目录
  • 原文地址:https://www.cnblogs.com/wujiyang/p/4420084.html
Copyright © 2011-2022 走看看