相关定义

  • 串的定长顺序储存采取顺序存储结构,存在长度上限,超出部分会截去。为克服此弊病唯有不限定长度上限,即采用动态分配串的储存空间。
  • 堆分配储存特点:仍以一组地址连续的储存单元存放地址序列,但存储空间是在程序执行过程中动态分配而得。
  • 堆:在C语言中,存在一个称为堆的自由存储区,有动态分配函数malloc()和free()管理。

堆分配存储的表示与实现

  • 堆分配储存的表示
typedef struct{
    char *ch;//字符串的储存区,非空时按照长度分配储存区,空时为NULL
    int length;
}HString;
  • 相关操作函数的表示
Status InitHStr(HString *S);
int StrLen(char Str);
Status HeapStrAssign(HString *S, char *chars);
int HeapStrLength(HString S);
int HeapStrCompare(HString S, HString T);
Status ClearHeapStr(HString *S);
Status SubHeapStr(HString S, HString *subStr, int pos, int length);
Status ConcatHeapStr(HString *H, HString S, HString T);
Status HeapStrCopy(HString S, HString *copyStr);
void TraverseHeapStr(HString S);
  • 初始化
Status InitHStr(HString *S){
    S->ch=NULL;
    S->length=0;
    return OK;
    //在初始化一个串的时候一定要将ch指向NULL和串的长度标记为0,不然在后续操作中判断ch是否存在或者求串的长度会出现问题
}
  • 求字符串长度
int StrLen(char *S){//字符串指针,加上不是为了改变S,而是为了能够用数组的形式表示字符串中的字符
    int length=0;
    while(S[length]){
        length++;
    }
    return length;
}
  • 赋值

Status HeapStrAssign(HString *S,char *chars){
    S->length=StrLen(chars);//获得长度
    if(S->ch){
        free(S->ch);
    }//检查是否为空
    S->ch=(char*)malloc(S->length*sizeof(char));
    if(S->ch){
        return OVERFLOW;
    }
    for(int i=0;i<S->length;i++){
        S->ch[i]=chars[i];
    }
    return OK;
}
  • 得到字符串长度

int HeapStrLength(HString S){
    return S.length;
}
  • 比较字符串大小
int HeapStrCompare(HString S, HString T){
    for(int i=0;i<S.length&&i<T.length;i++){
        if(S.ch[i]!=T.ch[i]){
            return S.ch[i]-T.ch[i];
        }
    }
    return S.length-T.length;
}

比较的时候,从字符串左边开始,一次比较每个字符,直接出现差异、或者其中一个串结束为止。

比如ABC与ACDE比较,第一个字符相同,继续比较第二个字符,由于第二个字符是后面一个串大,所以不再继续比较,结果就是后面个串大。

再如ABC与ABC123比较,比较三个字符后第一个串结束,所以就是后面一个串大。

所以,长度不能直接决定大小,字符串的大小是由左边开始最前面的字符决定的。

  • 清空字符串
Status ClearHeapStr(HString *S){
    if(S&&S->ch){
        free(S->ch);
        S->ch=NULL;
        S->length=0;
        return OK;
    }
    return ERROR;
}
  • 返回子串
Status SubHeapStr(HString S, HString *subStr, int pos, int length){
    if(pos<=0||length<=0||pos>S.length||length>S.length-pos+1){
        return ERROR;
    }
    if(subStr->ch){
        free(subStr->ch);
    }
    subStr->length=length;
    for(int i=0;i<length;i++){
        subStr->ch[i]=S.ch[pos-1+i];
    }
    return OK;
}
  • 串联两个字符串
Status ConcatHeapStr(HString *H, HString S, HString T){
    H->length=S.length+T.length;
    if(H->ch){
        free(H->ch);
    }
    H->ch=(char*)malloc(H->length*sizeof(char));
    if(!H->ch){
        return OVERFLOW;
    }
    for(int i=0;i<S.length;i++){
        H->ch[i]=S.ch[i];
    }
    for(int i=0;i<T.length;i++){
        H->ch[S.length+i]=T.ch[i];
    }
    return OK;
}
  • 复制字符串
Status HeapStrCopy(HString S, HString *copyStr){
    if(copyStr->ch){
        free(copyStr);
    }
    copyStr->length=S.length;
    copyStr->ch=(char*)malloc(copyStr->length*sizeof(char));
    if(!copyStr->ch){
        return OVERFLOW;
    }
    for(int i=0;i<S.length;i++){
        copyStr->ch[i]=S.ch[i];
    }
    return OK;
}
  • 遍历字符串
void TraverseHeapStr(HString S){
    for(int i=0;i<S.length;i++){
        printf("%c",S.ch[i]);
    }
    printf("\nThe length of the string:%d",S.length);
}

无欲则刚
76 声望15 粉丝