堆分配存储的串的表示和实现

串的堆分配存储结构

struct HString
{
    char * ch;//若是非空串,则按串长分配存储区;否则ch为NULL
    int length;//串长度
};

堆分配存储的串的12个基本操作

#define DestroyString ClearString//DestroyString()和ClearString()作用相同

void InitString(HString &S){
    S.length = 0;
    S.ch = NULL;
}

void ClearString(HString &S){
    free(S.ch);
    InitString(S);
}

Status StrAssign(HString &T, char *chars){//生成一个其值等于chars的串T
    int i, j;
    if (T.ch)//T指向某存储单元
        free(T.ch);//释放T原有存储空间
    i = strlen(chars);//求chars的长度i
    if (!i)//chars的长度为0
        InitString(T);//生成空串
    else//chars的长度不为0
    {
        T.ch = (char *)malloc(i * sizeof(char));//分配串存储空间
        if (!T.ch)//分配串存储空间失败
            exit(OVERFLOW);
        for (j = 0; j  < i; j ++)//分配串存储空间成功后,复制串chars[]到串T
            T.ch[j] = chars[j];
        T.length = i;//更新串T的长度
    }
}

void StrCopy(HString &T, HString S){//由串S复制得串T
    int i;
    if (T.ch)//串T不空
        free(T.ch);//释放串T原有存储空间
    T.ch = (char *)malloc(S.length * sizeof(char));//分配串存储空间
    if (!T.ch)//分配串存储空间失败
        exit(OVERFLOW);
    for (i = 0; i < S.length; i++)//从第1个字符到最后一个字符
        T.ch[i] = S.ch[i];//逐一复制字符
    T.length = S.length;//复制串长
}

Status StrEmpty(HString S){//若S为空串,则返回TRUE,否则返回FALSE
    if (S.length == 0 && S.ch == NULL)//空串标志
        return TRUE;
    else
        return FALSE;
}

int StrCompare(HString S, HString T){//若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
    int i;
    for (i = 0; i < S.length && i < T.length; i++)//在有效范围内
    if (S.ch[i] != T.ch[i])//逐一比较字符
        return S.ch[i] - T.ch[i];//不相等,则返回2字符ASCII码之差
    return S.length - T.length; //在有效范围内,字符相等,但长度不等,返回长度之差
}

int StrLength(HString S){
    return S.length;
}

Status Concat(HString &T, HString S1, HString S2){//用T返回S1和S2连接而成的新串。若未截断,则返回TRUE;否则返回FALSE
    int i;
    if (T.ch)//串T不空
        free(T.ch);//释放串T原有存储空间
    T.length = S1.length + S2.length;//串T的长度 = 串S1的长度 + 串S2的长度
    T.ch = (char *)malloc(T.length * sizeof(char));//分配串T的存储空间
    if (!T.ch)//分配串存储空间失败
        exit(OVERFLOW);
    for (i = 0; i < S1.length; i++)//将串S1的字符逐一复制给串T
        T.ch[i] = S1.ch[i];
    for (i = 0; i < S2.length; i++)//将串S2的字符逐一复制给串T(接在串S1的字符之后)
        T.ch[S1.length + i] = S2.ch[i];
}

Status SubString(HString &Sub, HString S, int pos, int len){//用Sub返回串S的自第pos个字符起长度为len的子串
    int i;
    if (pos<1 || pos > S.length || len < 0 || len > S.length - pos + 1)//pos和len的值超出范围
        return ERROR;//无法用Sub返回子串
    if (Sub.ch)//串Sub不空
        free(Sub.ch);//释放串Sub原有存储空间
    if (!len)//空子串
        InitString(Sub);//初始化串Sub
    else//完整子串
    {
        Sub.ch = (char *)malloc(len * sizeof(char));//分配串Sub的存储空间
        if (!Sub.ch)//分配串存储空间失败
            exit(OVERFLOW);
        for (i = 0; i <= len - 1; i++)//将串S第pos个字符起长度为len的子串的字符逐一复制给串Sub
            Sub.ch[i] = S.ch[pos - 1 + i];
        Sub.length = len;//串Sub的长度
    }
    return OK;
}

Status StrInsert(HString &S, int pos, HString T){//在串S的第pos个字符之前插入串T。
    int i;
    if (pos < 1 || pos > S.length + 1)//pos不合法
        return ERROR;
    if (T.length){//T非空
        S.ch = (char *)realloc(S.ch, (S.length + T.length) * sizeof(char));//重分S存储空间
        if (!S.ch)//重新分配串S的存储空间失败
            exit(OVERFLOW);
        for (i = S.length - 1; i >= pos - 1; --i)//为插入T而腾出位置
            S.ch[pos - 1 + i] = T.ch[i];
        for (i = 0; i < T.length; i++)//插入T
            S.ch[pos - 1 + i] = T.ch[i];
        S.length += T.length;//更新串S的长度
    }
    return OK;
}

Status StrDelete(HString &S, int pos, int len){//从串S中删除自第pos个字符起长度为len的子串
    int i;
    if (S.length < pos + len - 1)//pos和len的值超出范围
        return ERROR;
    for (i = pos - 1; i <= S.length - len; i++)//将待删除子串之后的字符逐一前移
        S.ch[i] = S.ch[i + len];
    S.length -= len;//更新串S的长度
    S.ch = (char *)realloc(S.ch, S.length * sizeof(char));//重新分配串S的存储空间(减少)
    return OK;
}

void StrPrint(HString S){
    int i;
    for (i = 1; i <= S.length; i++)
        printf("%c", S.ch[i]);
    printf("\n");
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值