串的堆式存储结构

来源:岁月联盟 编辑:exp 时间:2012-10-29

在C和C++语言中 ,提供一个称之为“堆”的共享空间,可以在程序运行过程中,系统利用函数malloc( )和free( )动态地申请或释放一块连续空间。
由于在C和C++语言中可以用指针对数组进行访问和操作,在串的存储和操作上也可以充分利用上述特性。
串的堆式存储结构类似于线性表的顺序存储结构,以一组地址连续的存储单元存放串值字符序列,其存储空间是在程序执行过程中动态分配的,而不是静态分配的。
串的堆式存储结构定义

Typedef struct  {  char *ch;   //指针域,指向存放串值的存储空间基址    int length;  // 整型域:存放串长  }HString;
说明:在这种存储结构下,由于串仍然是以数组存储的字符序列表示,因此此类串的操作是先为新生成的串分配一个存储空间,然后进行“字符序列的复制”。例如,如串插入操作StrInsert(S,pos ,T)(将串T插入到串S的第pos字符之前)的算法是,为串S重新分配大小等于串S和串T长度之和的存储空间,然后进行将S和T串值复制到新分配存储空间中。
串的一系列实现 www.2cto.com


/*
  串的堆式存储表示
 */ 
#include<stdio.h> 
#include<stdlib.h> 
#define OVERFLOW   -2//堆溢出 
#define OK          1//函数执行成功 
#define ERROR      -1//函数执行失败 
typedef int datatype; 
typedef struct{ 
    char*  ch;//指针域,指向存放串值的存储空间基址 
    int len;// 整型域:存放串长 
}HString; 
//初始化一个空串 
datatype InitHString(HString* s) 

    s->ch=(char*)malloc(sizeof(char)); 
    if(NULL==s->ch) return OVERFLOW; 
    s->ch=NULL; 
    s->len=0; 
    return OK; 

//为串赋值 
datatype assigment_string(HString* s, const char* str) 

    if(s->ch) free(s->ch); 
    int  length=0,i; 
    while(str[length]!='/0') 
        length++; 
    s->ch=(char*)malloc(length*sizeof(char)); 
    if(!s->ch) return OVERFLOW; 
    for(i=0;i<length;i++) 
        *(s->ch+i)=*(str+i); 
    s->len=length; 
    *(s->ch+s->len)='/0'; 
    return OK; 

//打印 
void PrintString(const HString* s) 

    int i=0; 
    while(*(s->ch+i)!='/0') 
    { 
        printf("%c",*(s->ch+i)); 
        i++; 
    } 
    printf("/n"); 

//求串的长度 
datatype GetLength(const HString* s) 

    int len=0; 
    while(*(s->ch+len)!='/0') 
        len++; 
    return len; 

//查找某个字符的位置,返回位序 
datatype HSLocal(const HString* s,char c) 

    int i; 
    for(i=0;i<s->len;i++) 
    { 
        if(c==*(s->ch+i)) 
            return i+1; 
    } 
    return -1; 

//串的连接 
datatype HSCat(HString* s,const HString* t) 

    int i=0; 
    char*  temp=(char*)malloc((s->len+t->len)*sizeof(char)); 
    if(!temp) return  OVERFLOW; 
    for(i=0;i<s->len;i++) 
        *(temp+i)=*(s->ch+i); 
    free(s->ch);//释放防止内存泄漏 
    for(i=0;i<t->len;i++) 
        *(temp+i+s->len)=*(t->ch+i); 
    s->len+=t->len; 
    s->ch=temp;//使s->ch重新指向temp 
    *(s->ch+s->len)='/0';       
    return OK; 

datatype HSCopy(HString* to, const   HString* from) 

    //如果目标串不为空则清空    
[cpp] view plaincopy
        if(to->ch) 
    { 
        free(to->ch); 
        to->ch=NULL; 
        to->len=0; 
    } 
    int i=0; 
    to->len=from->len; 
    to->ch=(char*)malloc(from->len*sizeof(char)); 
    if(!to->ch) return OVERFLOW; 
    for(i=0;i<from->len;i++) 
        *(to->ch+i)=*(from->ch+i); 
    *( to->ch+to->len)='/0'; 
    return OK; 
 

//在串s的pos位置处插入串t 
datatype HSInsert(HString* s,const HString *t,int pos) 

    if(pos<0 || pos>s->len) 
        return ERROR; 
    else{ 
        s->ch=(char*)realloc(s->ch,(s->len+t->len)*sizeof(char)); 
        int i,j=1; 
        //后移 
        for(i=s->len+t->len-1;i>=pos+t->len;i--) 
        { 
            *(s->ch+i)=*(s->ch+(s->len-j)); 
            j++;    
        } 
        //insert   
        for(i=0;i<t->len;i++) 
            *(s->ch+i+pos)=*(t->ch+i); 
    } 
    s->len+=t->len; 
    *(s->ch+s->len)='/0'; 
    return OK; 

//在串s的index位置删除长度为x个字符 
datatype HSdel(HString* s,int index,int x) 

    // index value invalid 
    if(index<0 || index>s->len) return ERROR; 
    //  if x+index> s->len 
    if((index+x)>=s->len) 
        s->len=index;      
    else 
    { 
        int i; 
        for(i=index;i<s->len;i++) 
        { 
            *(s->ch+i)=*(s->ch+i+x); 
        }  
        s->len-=x; 
    } 
    *(s->ch+s->len)='/0'; 
    return OK; 

//串比较 
datatype HScomp(const HString* s1,const HString* s2) 

    int i=0; 
    for(i=0;i<s1->len && i<s2->len;i++) 
    { 
        if(*(s1->ch+i)!=*(s2->ch+i)) 
            return *(s1->ch+i)-*(s2->ch+i); 
    } 
    return 0;//equal 

/*串的提取
 *   在串s中的index开始长度为length的子串提取到temp串中
 * */ 
datatype  HSsub(HString* temp,const HString* s,int index,int length) 

    if(index<0 || index>s->len) return ERROR; 
    if(length > s->len)    length=s->len-index; 
    temp->len=length; 
    temp->ch=(char*)malloc(length*sizeof(char)); 
    if(!temp->ch) return OVERFLOW; 
    int i; 
    for(i=0;i<length;i++) 
    { 
        *(temp->ch+i)=*(s->ch+index+i); 
    } 
    *(temp->ch+temp->len)='/0'; 
    return OK; 

//串的替换,把串s的从index开始长度为length的子串,用串t替换掉 
datatype HSReplace(HString* s,int index,int length,const HString*t) 

    if(index<0 || index>s->len ) 
        return ERROR; 
    //如果length大于串s的长度就替换掉从index后的所有字符 
    if(length>s->len) 
        length=s->len; 
    int i; 
    for(i=0;i<length;i++) 
    { 
        *(s->ch+i+index)=*(t->ch+i); 
    } 
    *(s->ch+s->len)='/0'; 
    return OK; 

int main(int argc ,char** argv) 

    // bulid string 
    HString S; 
    InitHString(&S); 
    assigment_string(&S,"hello world!"); 
    PrintString(&S); 
    printf("length=%d/n",GetLength(&S)); 
 
#if 0 
    //localion 
    int local=HSLocal(&S,'w'); 
    printf("local=%d/n",local); 
    free(S.ch); 
#endif  
 
#if 0 
    // insert 
    HString  S1; 
    InitHString(&S1); 
    assigment_string(&S1,"****"); 
    HSInsert(&S,&S1,2);  
    PrintString(&S); 
    printf("length=%d/n",GetLength(&S)); 
    free(S1.ch); 
#endif 
#if 0    
    // copy 
    HString S2; 
    InitHString(&S2); 
    assigment_string(&S2,"beijing"); 
    HSCopy(&S,&S2); 
    PrintString(&S); 
    printf("length=%d/n",GetLength(&S)); 
    free(S.ch); 
    free(S2.ch); 
#endif 
#if 0 
    //cat  
    HString S3; 
    InitHString(&S3); 
    assigment_string(&S3,"////"); 
    HSCat(&S,&S3); 
    PrintString(&S); 
    printf("length=%d/n",GetLength(&S)); 
    free(S3.ch); 
    free(S.ch); 
#endif  
 
#if 0 
    // delete  
    HSdel(&S,2,5); 
    PrintString(&S); 
    printf("length=%d/n",GetLength(&S)); 
    free(S.ch); 
#endif  
 
#if 0 
    // complar  
    HString S4; 
    InitHString(&S4); 
    assigment_string(&S4,"hello world!"); 
    datatype ret=HScomp(&S,&S4); 
    if(ret>0) 
        printf("S>S4/n"); 
    else if(ret<0) 
        printf("S<S4/n"); 
    else  
        printf("S=S4/n"); 
    free(S4.ch); 
    free(S.ch); 
#endif 
 
#if 0 
    // sub 
    HString S5; 
    HSsub(&S5,&S,2,5); 
    PrintString(&S5); 
    printf("length=%d/n",GetLength(&S5)); 
    free(S.ch); 
    free(S5.ch); 
#endif 
 
#if 1        
    // replace 
    HString S6; 
    InitHString(&S6); 
    assigment_string(&S6,"************************************"); 
    HSReplace(&S,2,50,&S6); 
    PrintString(&S); 
    printf("length=%d/n",GetLength(&S)); 
    free(S6.ch); 
    free(S.ch); 
 
#endif 
    //      free(S.ch); 
    return 0;