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

计算机上非数值处理的对象基本上是字符串数据,在较早的程序设计语言中,字符串是作为输入输出的常量出现。随着语言程序的加工和发展产生了字符串处理。但是现在我们用的计算机硬件结构主要反应的数值计算的需要。因此,在处理字符串数据时比处理整型数和浮点数要复杂的多,而且在不同的类型应用中,所处理的字符串具有不同的特点,要有效的实现字符串的处理,就必须更具具体情况使用合适的存储结构,如:定长顺序存储结构,堆分配存储结构,块链存储结构。定长顺序存储结构比较简单,我们就不单独讨论。本篇博客我们讨论一下堆分配存储结构的串

名词解释

名词 解释
由零个或多个字符组成的有限序列
长度 串中字符的个数
空串 零个字符的串
子串 串中任一连续的字符组成的串
组串 包含了子串的的串相应的成为主串
位置 通常字符在串中的序列称为该字符在串中的位置

串的堆分配存储结构

typedef struct {
    
    char *ch;       
    int length;
}HeapString;

基本操作

  • HeapString InitHeapStr();
  • Status HeapStrAssign(HeapString *hStr, char *chars);
  • int HeapStrLength(HeapString s);
  • int HeapStrCompare(HeapString hStr_1, HeapString hStr_2);
  • Status ClearHeapStr(HeapString *hStr);
  • Status SubHeapStr(HeapString hStr, HeapString *subStr, int pos, int length);
  • Status ConcatHeapStr(HeapString *desHStr, HeapString srcHStr_1, HeapString srcHStr_2);
  • Status HeapStrCopy(HeapString *desHStr, HeapString srcHStr);
  • void PrintHeapStr(HeapString hStr);

基本操作实现

初始化

HeapString InitHeapStr() {
    
    HeapString hStr;
    hStr.ch = NULL;
    hStr.length = 0;
    return hStr;
}

注意:在初始化一个串的时候一定要将ch指向NULL和串的长度标记为0,不然在后续操作中判断ch是否存在或者求串的长度出现问题

赋值

int StrLen(char *s) {
    
    int length = 0;
    while(s[length] != '\0') {
                    
        length++;
    }
    return length;
}

Status HeapStrAssign(HeapString *hStr, char *chars) {
    
    if(hStr->ch) {
        
        printf("test: hStr->ch");
        free(hStr->ch);
    }
    hStr->length = 0;
    int length = StrLen(chars);
    if (!(hStr->ch = (char *)malloc(length * sizeof(char)))) {
                                                        
        printf("%s error : 内存溢出\n", __func__);
        return OVERFLOW;
    } else {

        for (int i = 0; i < length; i++) {
                                            
            hStr->ch[i] =  chars[i];
            hStr->length += 1;
        }
        return OK;
    }
}

注意:在赋值之前需要先检测hStr->是否被分配过内存,如果被分配过内存则需要先free不然会造成内存泄漏

获取串的长度

int HeapStrLength(HeapString s) {
    
    return s.length;
}

比较串的大小

int HeapStrCompare(HeapString hStr_1, HeapString hStr_2) {
    
    if (hStr_1.length == hStr_2.length) {
                
        return 0;
    } else if (hStr_1.length > hStr_2.length) {
                                    
        return 1;
    } else {
        return -1;
    }
}

注意:这里的比较大小并不是比较串的长度,而已将两个串中的字符对应的ASCII码进行逐一的比较,一旦遇到ASCII码值不一样的就马上返回结果

清除字符串

Status ClearHeapStr(HeapString *hStr) {
    
    if(hStr && hStr->ch) {
                
        free(hStr->ch);
        hStr->ch = NULL;
        hStr->length = 0;
        return OK;
    } else {
        
        printf("%s error : 参数错误\n", __func__);
        return ERROR;
    }
}

注意:清除分配空间的时候别忘记了更新串的长度

连接两个串

Status ConcatHeapStr(HeapString *desHStr, HeapString srcHStr_1, HeapString srcHStr_2) {
    
    int length = srcHStr_1.length + srcHStr_2.length;
    if (desHStr->ch) {
    
        free(desHStr->ch);
        desHStr->length = 0;
    }
    if (!(desHStr->ch = (char *)malloc(length * sizeof(char)))) {
        
        printf("%s error : 内存溢出\n", __func__);
        return OVERFLOW;
    }
    for (int i = 0; i < srcHStr_1.length; i++) {

        desHStr->ch[i] = srcHStr_1.ch[i];
        desHStr->length += 1;
    }
    for (int i = 0; i < srcHStr_2.length; i++) {
        
        desHStr->ch[srcHStr_1.length+i] = srcHStr_2.ch[i];
        desHStr->length += 1;
    }
    return OK;
}

获取子串

Status SubHeapStr(HeapString hStr, HeapString *subStr, int pos, int length) {
    
    if (length <= 0 || pos <= 0 || hStr.length < length) {
        
        printf("%s error : 参数错误\n", __func__);
        return ERROR;
    }
    if (subStr->ch) {
        
        free(subStr->ch);
        subStr->length = 0;
    }
    if (!(subStr->ch = (char *)malloc(length * sizeof(char)))) {
        
        printf("%s error : 内存溢出\n", __func__);
        return OVERFLOW;
    }
    for (int i = 0; i < length; i++) {
        
        subStr->ch[i] = hStr.ch[pos-1+i];
        subStr->length += 1;
    }
    return OK;
}

注意:获取子串的时候操作位置和长度的异常处理

拷贝串

Status HeapStrCopy(HeapString *desHStr, HeapString srcHStr) {
    
    if (desHStr->ch) {
        
        free(desHStr->ch);
        desHStr->length = 0;
    }
    if (!(desHStr->ch = (char *)malloc(srcHStr.length * sizeof(char)))) {
    
        printf("%s error : 内存溢出\n", __func__);
        return OVERFLOW;
    }
    for (int i = 0; i < srcHStr.length; i++) {
        
        desHStr->ch[i] = srcHStr.ch[i];
        desHStr->length += 1;
    }
    return OK;
}

注意:此处拷贝为深拷贝,不能简单的指针赋值

打印串信息

void PrintHeapStr(HeapString hStr) {
    
    printf("HeapString info\n\tch:");
    for (int i = 0; i < hStr.length; i++) {
    
        printf("%c", hStr.ch[i]);   
    }
    printf("\n\tlen: %d \n", hStr.length);
}

欢迎讨论

Email:[email protected]

Github:https://github.com/LHCoder2016/DataStructure

你可能感兴趣的:(串的堆分配存储表示和实现)