【数据结构】串的堆分配存储表示

本文提供了一段C语言代码,实现了对串的若干基本操作,包括初始化、复制、清空、比较、连接、获取子串、查找子串、插入和删除等。代码中使用了动态内存分配来存储串,并提供了相应的操作函数和主函数供用户交互操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

⭐️写在前面的话⭐️

📒博客主页: 程序员好冰
🎉欢迎 【点赞👍 关注🔎 收藏⭐️ 留言📝】
📌本文由 程序员好冰 原创,优快云 首发!
📆入站时间: 🌴2022 年 07 月 13 日🌴
✉️ 是非不入松风耳,花落花开只读书。
💭推荐书籍:📚《Java编程思想》,📚《Java 核心技术卷》
💬参考在线编程网站:🌐牛客网🌐力扣
🍭 作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!🍭


串的定长存储表示

自定义声明

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//串的堆分配表示
/*注意:下标从0开始*/

#define OK 1
#define ERROR 0

#define TRUE 1
#define FALSE 0

typedef int Status;

typedef struct HString
{
    char *ch;
    int length;
}HString,*HeString;

0、打印一个串

//0、打印一个串
/*注意是从下标0开始打印*/
Status Print_String(HeString S)
{
    int i;
    for(i=0;i<S->length;i++){
        printf("%c",S->ch[i]);
    }
    printf(".\n");
    return OK;
}

1、键盘输入字符数组,并生成串S

//1、键盘输入字符数组,并生成串S
Status StrAssign(HeString S,char *chars)
{
    int len,i;
    len=strlen(chars);
    S->ch=(char*)malloc(len*sizeof(char));
    for(i=0;i<len;i++){
        S->ch[i]=chars[i];
    }
    S->length=len;
    return OK;
}

2、复制S串到空串T中

//2、复制S串到空串T中
Status StrCopy(HeString T,HeString S)
{
    T->ch=(char*)malloc(S->length*sizeof(char));
    int i;
    for(i=0;i<=S->length;i++){
        T->ch[i]=S->ch[i];
    }
    T->length=S->length;
    printf("串复制成功.\n");
    printf("复制后串T为:");
    Print_String(T);
    return OK;
}

3、清空串S

//3、清空串S
Status ClearString(HeString S)
{
    int i;
    for(i=S->length-1;i>=0;i--){
        S->ch[i]='\0';
    }
    if(S->ch){
        free(S->ch);
    }
    S->ch=NULL;
    S->length=0;
    return OK;
}

4、判断串S是否为空

//4、判断串S是否为空
Status StringEmpty(HeString S)
{
    if(S->length==0){
        return TRUE;
    }
    return FALSE;
}

5、返回串S的元素个数

//5、返回串S的元素个数
int StrLength(HeString S)
{
    return S->length;
}

6、按字符比较两个串(S,W)的大小

//6、按字符比较两个串(S,W)的大小
/*
    比较的原理:
        ·abc与abc:两个串相等
        ·abc与ab:比较长度
        ·abc与acd:比较ASCII码
*/
int StrCompare(HeString S,HeString W)
{
    int i;
    for(i=0;i<S->length&&i<W->length;i++){
        if(S->ch[i]!=W->ch[i]){
            return S->ch[i]-W->ch[i];
        }
    }
    return S->length-W->length;
}

7、连接两个串S,S2,获得新串R

//7、连接两个串S,S2,获得新串R
Status Concat(HeString S,HeString S2,HeString R)
{
    R->ch=(char*)malloc((S->length+S2->length)*sizeof(char));
    R->length=(S->length+S2->length);
    int i,j;
    for(i=0;i<StrLength(S);i++){
        R->ch[i]=S->ch[i];
    }
    for(i=StrLength(S),j=0;i<R->length;i++,j++){
        R->ch[i]=S2->ch[j];
    }
    printf("连接后的新串R为:");
    Print_String(R);
    return OK;
}

8、获得指定位置,指定长度的子串s

//8、获得指定位置,指定长度的子串s
Status SubString(HeString S,HeString s,int pos,int len)
{
    if(pos<0||pos>=S->length||len<0||pos+len>S->length){
        printf("输入的数据不合法.\n");
        return ERROR;
    }
    if(len==0){
        s->ch=NULL;
        s->length=0;
    }
    if(len!=0){
        int i,j;
        s->ch=(char*)malloc(len*sizeof(char));
        for(i=pos,j=0;i<=pos+len-1;i++,j++){
            s->ch[j]=S->ch[i];
        }
        s->length=len;
    }
    return OK;
}

9、返回从第pos个位置开始S第一次出现子串m的相对位置

//9、返回从第pos个位置开始S第一次出现子串m的相对位置
/*不存在就返回0*/
int Index(HeString S,HeString m,int pos)
{
    if(pos<0){
        printf("输入的数据有误.\n");
        return ERROR;
    }
    HeString sub;//临时的子串
    sub->ch=(char*)malloc(m->length*sizeof(char));
    sub->length=m->length;
    int i;
    i=pos;//记录主串的位置
    /*
    举例:
        S:1234567(7)
        m:567(3)
        pos:4
        i:4
        i==S[0]-m[0]
    */
    while(i<=S->length-m->length){
        SubString(S,sub,i,m->length);
        if(StrCompare(sub,m)!=0){
            i++;
        }
        if(StrCompare(sub,m)==0){
            return i-1;
        }
    }
    return 0;
}

10、在串S的第pos个字符之前插入串U

//10、在串S的第pos个字符之前插入串U
Status StrInsert(HeString S,HeString U,int pos)
{
    if(pos<0||pos>S->length){
        printf("输入的数据有误,请重新输入.\n");
        return ERROR;
    }
    int i,j;
    S->ch=(char*)realloc(S->ch,(S->length+U->length)*sizeof(char));
    //先向后挪
    for(i=S->length-1;i>=pos;i--){
        S->ch[i+U->length]=S->ch[i];
    }
    //在往空位中插
    for(i=pos,j=0;i<U->length;i++,j++){
        S->ch[i]=U->ch[j];
    }
    S->length=S->length+U->length;
    return OK;
}

11、从串S删除第pos个字符起长度为len的子串

//11、从串S删除第pos个字符起长度为len的子串
Status StrDelete(HeString S,int pos,int len)
{
    if(pos<0||pos>S->length-len||len<0){
        printf("输入的数据有误,请重新操作.\n");
        return ERROR;
    }
    int i;
    for(i=pos;i<pos+len;i++){
       S->ch[i]=S->ch[i+len];
    }
    S->length-=len;
    return OK;
}

主函数

int main()
{
    /*
        S:初始化的主串
        T:复制过来的串
        R:串S和串T连接后的新串
        s:子串
    */
    HString S,T,W,S2,R,s,m,U;
    char chars_S[1024];
    char chars_W[1024];
    char chars_S2[1024];
    char chars_m[1024];
    char chars_U[1024];
    int input,i;
    int pos;
    int len;
    printf("请继续操作...\n");
    while(1){
        printf("\n==========================\n");
        printf("0、打印主串S.\n");
        printf("1、键盘输入字符数组,并生成串S.\n");
        printf("2、复制S串到空串T中.\n");
        printf("3、清空串S.\n");
        printf("4、判断串S是否为空.\n");
        printf("5、返回串S的元素个数.\n");
        printf("6、按字符比较两个串(S和W)的大小.\n");
        printf("7、连接两个串S,S2,获得新串R.\n");
        printf("8、获得指定位置,指定长度的子串s.\n");
        printf("9、返回从第pos个位置开始S第一次出现子串m的相对位置.\n");
        printf("10、在串S的第pos个字符之前插入串U.\n");
        printf("11、从串S删除第pos个字符起长度为len的子串.\n");
        printf("==========================\n");
        printf("请输入对应操作的序号:");
        scanf("%d",&input);
        switch(input)
        {
        case 0:
            if(StrLength(&S)==0){
                printf("串为空,请先初始化.\n");
            }else
            {
                printf("主串S为:");
                Print_String(&S);
            }
            break;
        case 1:
            printf("请输入一个字符数组(用以构造主串S):");
            scanf("%s",chars_S);
            StrAssign(&S,chars_S);
            break;
        case 2:
            StrCopy(&T,&S);
            break;
        case 3:
            ClearString(&S);
            break;
        case 4:
            if(StringEmpty(&S)==TRUE){
                printf("串S为空.\n");
            }
            if(StringEmpty(&S)==FALSE){
                printf("串S不为空.\n");
            }
            break;
        case 5:
            printf("主串的长度为:%d.\n",StrLength(&S));
            break;
        case 6:
            printf("初始化串W:");
            scanf("%s",chars_W);
            StrAssign(&W,chars_W);
            int result=StrCompare(&S,&W);
            if(result>0){
                printf("串S更大.\n");
            }
            if(result==0){
                printf("串S和串W相等大小.\n");
            }
            if(result<0){
                printf("串W更大.\n");
            }
            break;
        case 7:
            printf("初始化串S2:");
            scanf("%s",chars_S2);
            StrAssign(&S2,chars_S2);
            Concat(&S,&S2,&R);
            break;
        case 8:
            printf("请输入起始位置和长度(pos,len):");
            scanf("%d,%d",&pos,&len);
            SubString(&S,&s,pos,len);
            printf("获得的子串s为:");
            Print_String(&s);
            break;
        case 9:
            printf("初始化串m:");
            scanf("%s",chars_m);
            StrAssign(&m,chars_m);
            printf("从第几个位置开始查找(pos):");
            scanf("%d",&pos);
            i=Index(&S,&m,pos);
            if(i==0){
                printf("主串S中不存在m这样的子串.\n");
            }else
            {
                printf("在第%d个位置出现该子串.\n",i-pos+1);
            }
            break;
        case 10:
            printf("初始化要插入的串U:");
            scanf("%s",chars_U);
            StrAssign(&U,chars_U);
            printf("请输入要插入的位置(pos):");
            scanf("%d",&pos);
            StrInsert(&S,&U,pos);
            printf("串U插入成功.\n");
            printf("主串S为:");
            Print_String(&S);
            break;
        case 11:
            printf("请输入需要删除的起点以及长度(pos,len):");
            scanf("%d,%d",&pos,&len);
            StrDelete(&S,pos,len);
            printf("子串删除成功.\n");
            printf("主串S为:");
            Print_String(&S);
            break;
        default:
            printf("输入的序号有误,请重新输入.\n");
            break;
        }
    }
    return 0;
}

程序源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//串的堆分配表示
/*注意:下标从0开始*/

#define OK 1
#define ERROR 0

#define TRUE 1
#define FALSE 0

typedef int Status;

typedef struct HString
{
    char *ch;
    int length;
}HString,*HeString;

//0、打印一个串
/*注意是从下标0开始打印*/
Status Print_String(HeString S)
{
    int i;
    for(i=0;i<S->length;i++){
        printf("%c",S->ch[i]);
    }
    printf(".\n");
    return OK;
}

//1、键盘输入字符数组,并生成串S
Status StrAssign(HeString S,char *chars)
{
    int len,i;
    len=strlen(chars);
    S->ch=(char*)malloc(len*sizeof(char));
    for(i=0;i<len;i++){
        S->ch[i]=chars[i];
    }
    S->length=len;
    return OK;
}

//2、复制S串到空串T中
Status StrCopy(HeString T,HeString S)
{
    T->ch=(char*)malloc(S->length*sizeof(char));
    int i;
    for(i=0;i<=S->length;i++){
        T->ch[i]=S->ch[i];
    }
    T->length=S->length;
    printf("串复制成功.\n");
    printf("复制后串T为:");
    Print_String(T);
    return OK;
}

//3、清空串S
Status ClearString(HeString S)
{
    int i;
    for(i=S->length-1;i>=0;i--){
        S->ch[i]='\0';
    }
    if(S->ch){
        free(S->ch);
    }
    S->ch=NULL;
    S->length=0;
    return OK;
}

//4、判断串S是否为空
Status StringEmpty(HeString S)
{
    if(S->length==0){
        return TRUE;
    }
    return FALSE;
}

//5、返回串S的元素个数
int StrLength(HeString S)
{
    return S->length;
}

//6、按字符比较两个串(S,W)的大小
/*
    比较的原理:
        ·abc与abc:两个串相等
        ·abc与ab:比较长度
        ·abc与acd:比较ASCII码
*/
int StrCompare(HeString S,HeString W)
{
    int i;
    for(i=0;i<S->length&&i<W->length;i++){
        if(S->ch[i]!=W->ch[i]){
            return S->ch[i]-W->ch[i];
        }
    }
    return S->length-W->length;
}

//7、连接两个串S,S2,获得新串R
Status Concat(HeString S,HeString S2,HeString R)
{
    R->ch=(char*)malloc((S->length+S2->length)*sizeof(char));
    R->length=(S->length+S2->length);
    int i,j;
    for(i=0;i<StrLength(S);i++){
        R->ch[i]=S->ch[i];
    }
    for(i=StrLength(S),j=0;i<R->length;i++,j++){
        R->ch[i]=S2->ch[j];
    }
    printf("连接后的新串R为:");
    Print_String(R);
    return OK;
}

//8、获得指定位置,指定长度的子串s
Status SubString(HeString S,HeString s,int pos,int len)
{
    if(pos<0||pos>=S->length||len<0||pos+len>S->length){
        printf("输入的数据不合法.\n");
        return ERROR;
    }
    if(len==0){
        s->ch=NULL;
        s->length=0;
    }
    if(len!=0){
        int i,j;
        s->ch=(char*)malloc(len*sizeof(char));
        for(i=pos,j=0;i<=pos+len-1;i++,j++){
            s->ch[j]=S->ch[i];
        }
        s->length=len;
    }
    return OK;
}

//9、返回从第pos个位置开始S第一次出现子串m的相对位置
/*不存在就返回0*/
int Index(HeString S,HeString m,int pos)
{
    if(pos<0){
        printf("输入的数据有误.\n");
        return ERROR;
    }
    HeString sub;//临时的子串
    sub->ch=(char*)malloc(m->length*sizeof(char));
    sub->length=m->length;
    int i;
    i=pos;//记录主串的位置
    /*
    举例:
        S:1234567(7)
        m:567(3)
        pos:4
        i:4
        i==S[0]-m[0]
    */
    while(i<=S->length-m->length){
        SubString(S,sub,i,m->length);
        if(StrCompare(sub,m)!=0){
            i++;
        }
        if(StrCompare(sub,m)==0){
            return i-1;
        }
    }
    return 0;
}

//10、在串S的第pos个字符之前插入串U
Status StrInsert(HeString S,HeString U,int pos)
{
    if(pos<0||pos>S->length){
        printf("输入的数据有误,请重新输入.\n");
        return ERROR;
    }
    int i,j;
    S->ch=(char*)realloc(S->ch,(S->length+U->length)*sizeof(char));
    //先向后挪
    for(i=S->length-1;i>=pos;i--){
        S->ch[i+U->length]=S->ch[i];
    }
    //在往空位中插
    for(i=pos,j=0;i<U->length;i++,j++){
        S->ch[i]=U->ch[j];
    }
    S->length=S->length+U->length;
    return OK;
}

//11、从串S删除第pos个字符起长度为len的子串
Status StrDelete(HeString S,int pos,int len)
{
    if(pos<0||pos>S->length-len||len<0){
        printf("输入的数据有误,请重新操作.\n");
        return ERROR;
    }
    int i;
    for(i=pos;i<pos+len;i++){
       S->ch[i]=S->ch[i+len];
    }
    S->length-=len;
    return OK;
}

int main()
{
    /*
        S:初始化的主串
        T:复制过来的串
        R:串S和串T连接后的新串
        s:子串
    */
    HString S,T,W,S2,R,s,m,U;
    char chars_S[1024];
    char chars_W[1024];
    char chars_S2[1024];
    char chars_m[1024];
    char chars_U[1024];
    int input,i;
    int pos;
    int len;
    printf("请继续操作...\n");
    while(1){
        printf("\n==========================\n");
        printf("0、打印主串S.\n");
        printf("1、键盘输入字符数组,并生成串S.\n");
        printf("2、复制S串到空串T中.\n");
        printf("3、清空串S.\n");
        printf("4、判断串S是否为空.\n");
        printf("5、返回串S的元素个数.\n");
        printf("6、按字符比较两个串(S和W)的大小.\n");
        printf("7、连接两个串S,S2,获得新串R.\n");
        printf("8、获得指定位置,指定长度的子串s.\n");
        printf("9、返回从第pos个位置开始S第一次出现子串m的相对位置.\n");
        printf("10、在串S的第pos个字符之前插入串U.\n");
        printf("11、从串S删除第pos个字符起长度为len的子串.\n");
        printf("==========================\n");
        printf("请输入对应操作的序号:");
        scanf("%d",&input);
        switch(input)
        {
        case 0:
            if(StrLength(&S)==0){
                printf("串为空,请先初始化.\n");
            }else
            {
                printf("主串S为:");
                Print_String(&S);
            }
            break;
        case 1:
            printf("请输入一个字符数组(用以构造主串S):");
            scanf("%s",chars_S);
            StrAssign(&S,chars_S);
            break;
        case 2:
            StrCopy(&T,&S);
            break;
        case 3:
            ClearString(&S);
            break;
        case 4:
            if(StringEmpty(&S)==TRUE){
                printf("串S为空.\n");
            }
            if(StringEmpty(&S)==FALSE){
                printf("串S不为空.\n");
            }
            break;
        case 5:
            printf("主串的长度为:%d.\n",StrLength(&S));
            break;
        case 6:
            printf("初始化串W:");
            scanf("%s",chars_W);
            StrAssign(&W,chars_W);
            int result=StrCompare(&S,&W);
            if(result>0){
                printf("串S更大.\n");
            }
            if(result==0){
                printf("串S和串W相等大小.\n");
            }
            if(result<0){
                printf("串W更大.\n");
            }
            break;
        case 7:
            printf("初始化串S2:");
            scanf("%s",chars_S2);
            StrAssign(&S2,chars_S2);
            Concat(&S,&S2,&R);
            break;
        case 8:
            printf("请输入起始位置和长度(pos,len):");
            scanf("%d,%d",&pos,&len);
            SubString(&S,&s,pos,len);
            printf("获得的子串s为:");
            Print_String(&s);
            break;
        case 9:
            printf("初始化串m:");
            scanf("%s",chars_m);
            StrAssign(&m,chars_m);
            printf("从第几个位置开始查找(pos):");
            scanf("%d",&pos);
            i=Index(&S,&m,pos);
            if(i==0){
                printf("主串S中不存在m这样的子串.\n");
            }else
            {
                printf("在第%d个位置出现该子串.\n",i-pos+1);
            }
            break;
        case 10:
            printf("初始化要插入的串U:");
            scanf("%s",chars_U);
            StrAssign(&U,chars_U);
            printf("请输入要插入的位置(pos):");
            scanf("%d",&pos);
            StrInsert(&S,&U,pos);
            printf("串U插入成功.\n");
            printf("主串S为:");
            Print_String(&S);
            break;
        case 11:
            printf("请输入需要删除的起点以及长度(pos,len):");
            scanf("%d,%d",&pos,&len);
            StrDelete(&S,pos,len);
            printf("子串删除成功.\n");
            printf("主串S为:");
            Print_String(&S);
            break;
        default:
            printf("输入的序号有误,请重新输入.\n");
            break;
        }
    }
    return 0;
}

🚀先看后赞,养成习惯!🚀

🚀 先看后赞,养成习惯!🚀

🎈觉得文章写得不错的老铁们,点赞评论关注走一波!谢谢啦!🎈


评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值