【数据结构】串的定长顺序存储表示

⭐️写在前面的话⭐️

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


串的定长存储表示

自定义声明

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

//串的顺序存储,采用数组实现

#define OK 1
#define ERROR 0

#define TRUE 1
#define FALSE 0

#define MAX_SIZE 100

typedef int Status;

/*假如是String[10],就只能存9个字符*/
/*这里我们用String[0]存放串的长度*/
typedef char String[MAX_SIZE+1];

0、打印一个串

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

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

//1、键盘输入字符数组,并生成串S
Status StrAssign(String S,char *chars)
{
    if(strlen(chars)>MAX_SIZE){
        printf("字符串的长度超出范围.\n");
        return ERROR;
    }
    int i;
    S[0]=strlen(chars);
    for(i=1;i<=S[0];i++){
        S[i]=chars[i-1];
    }
    return OK;
}

2、复制S串到空串T中

//2、复制S串到空串T中
Status StrCopy(String T,String S)
{
    int i;
    for(i=1;i<=S[0];i++){
        T[i]=S[i];
    }
    T[0]=S[0];
    printf("串复制成功.\n");
    printf("复制后串T为:");
    Print_String(T);
    return OK;
}

3、清空串S

//3、清空串S
Status ClearString(String S)
{
    int i;
    for(i=0;i<S[0];i++){
        S[i]='\0';
    }
    printf("串S清空成功.\n");
    return OK;
}

4、判断串S是否为空

//4、判断串S是否为空
Status StringEmpty(String S)
{
    if(S[0]==0){
        return TRUE;
    }
    return FALSE;
}

5、返回串S的元素个数

//5、返回串S的元素个数
int StrLength(String S)
{
    return S[0];
}

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

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

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

//7、连接两个串S,S2,获得新串R
/*问题:连接后,新串的长度可能会超过MAX_SIZE*/
Status Concat(String S,String S2,String R)
{
    if(S[0]+S2[0]>MAX_SIZE){
        printf("连接后的新串R过长.\n");
        return ERROR;
    }
    int i,j;
    for(i=1;i<=S[0];i++){
        R[i]=S[i];
    }
    for(i=S[0]+1,j=1;j<=S2[0];i++,j++){
        R[i]=S2[j];
    }
    R[0]=S[0]+S2[0];
    printf("连接后的新串R为:");
    Print_String(R);
    return OK;
}

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

//8、获得指定位置,指定长度的子串s
Status SubString(String S,String s,int pos,int len)
{
    /*出错的情况:
        ·pos小于1
        ·pos大于主串的长度
        ·len小于0
        ·pos+len大于主串的长度+1*/
    //假设主串S[3],有S[1]、S[2]、S[3]3个元素
    //pos=1,len=3,就是S[1]、S[2]、S[3]3个元素,
    //pos+len等于主串的长度+1
    if(pos<1||pos>S[0]||len<0||pos+len>S[0]+1){
        printf("输入的数据不合法.\n");
        return ERROR;
    }
    int i,j;
    for(i=1,j=pos;j<=pos+len;i++,j++){
        s[i]=S[j];
    }
    s[0]=len;
    return OK;
}

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

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

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

//10、在串S的第pos个字符之前插入串U
Status StrInsert(String S,String U,int pos)
{
    if(pos<1||pos>S[0]+1){
        printf("输入的数据有误,请重新输入.\n");
        return ERROR;
    }
    if(S[0]+U[0]<=MAX_SIZE){
        //完全插入
        int i,j;
        //1、先往后移
        for(i=S[0];i>=pos;i--){
            //S[i+1]=S[i];//这是往后移一个
            S[i+U[0]]=S[i];//这是往后移T[0]个
        }
        //2、再往里填充
        for(i=pos,j=1;i<pos+U[0];i++,j++){
            S[i]=U[j];
        }
        //3、主串长度改变
        S[0]=S[0]+U[0];
    }else
    {
        //部分插入
        int len,i,j;
        len=MAX_SIZE-S[0];
        for(i=S[0];i>=pos;i--){
            S[i+len]=S[i];
        }
        for(i=pos,j=1;i<pos+len;i++,j++){
            S[i]=U[j];
        }
        S[0]=MAX_SIZE;
    }
    return OK;
}

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

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

主函数

int main()
{
    /*
        S:初始化的主串
        T:复制过来的串
        R:串S和串T连接后的新串
        s:子串
    */
    String 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(S[0]==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");
            Print_String(S);
            break;
        case 11:
            printf("请输入需要删除的起点以及长度(pos,len):");
            scanf("%d,%d",&pos,&len);
            StrDelete(S,pos,len);
            printf("子串删除成功.\n");
            Print_String(S);
            break;
        default:
            printf("输入的序号有误,请重新输入.\n");
            break;
        }
    }
    return 0;
}

程序源码

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

//串的顺序存储,采用数组实现

#define OK 1
#define ERROR 0

#define TRUE 1
#define FALSE 0

#define MAX_SIZE 100

typedef int Status;

/*假如是String[10],就只能存9个字符*/
/*这里我们用String[0]存放串的长度*/
typedef char String[MAX_SIZE+1];

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

//1、键盘输入字符数组,并生成串S
Status StrAssign(String S,char *chars)
{
    if(strlen(chars)>MAX_SIZE){
        printf("字符串的长度超出范围.\n");
        return ERROR;
    }
    int i;
    S[0]=strlen(chars);
    for(i=1;i<=S[0];i++){
        S[i]=chars[i-1];
    }
    return OK;
}

//2、复制S串到空串T中
Status StrCopy(String T,String S)
{
    int i;
    for(i=1;i<=S[0];i++){
        T[i]=S[i];
    }
    T[0]=S[0];
    printf("串复制成功.\n");
    printf("复制后串T为:");
    Print_String(T);
    return OK;
}

//3、清空串S
Status ClearString(String S)
{
    int i;
    for(i=0;i<S[0];i++){
        S[i]='\0';
    }
    printf("串S清空成功.\n");
    return OK;
}

//4、判断串S是否为空
Status StringEmpty(String S)
{
    if(S[0]==0){
        return TRUE;
    }
    return FALSE;
}

//5、返回串S的元素个数
int StrLength(String S)
{
    return S[0];
}

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

//7、连接两个串S,S2,获得新串R
/*问题:连接后,新串的长度可能会超过MAX_SIZE*/
Status Concat(String S,String S2,String R)
{
    if(S[0]+S2[0]>MAX_SIZE){
        printf("连接后的新串R过长.\n");
        return ERROR;
    }
    int i,j;
    for(i=1;i<=S[0];i++){
        R[i]=S[i];
    }
    for(i=S[0]+1,j=1;j<=S2[0];i++,j++){
        R[i]=S2[j];
    }
    R[0]=S[0]+S2[0];
    printf("连接后的新串R为:");
    Print_String(R);
    return OK;
}

//8、获得指定位置,指定长度的子串s
Status SubString(String S,String s,int pos,int len)
{
    /*出错的情况:
        ·pos小于1
        ·pos大于主串的长度
        ·len小于0
        ·pos+len大于主串的长度+1*/
    //假设主串S[3],有S[1]、S[2]、S[3]3个元素
    //pos=1,len=3,就是S[1]、S[2]、S[3]3个元素,
    //pos+len等于主串的长度+1
    if(pos<1||pos>S[0]||len<0||pos+len>S[0]+1){
        printf("输入的数据不合法.\n");
        return ERROR;
    }
    int i,j;
    for(i=1,j=pos;j<=pos+len;i++,j++){
        s[i]=S[j];
    }
    s[0]=len;
    return OK;
}

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

//10、在串S的第pos个字符之前插入串U
Status StrInsert(String S,String U,int pos)
{
    if(pos<1||pos>S[0]+1){
        printf("输入的数据有误,请重新输入.\n");
        return ERROR;
    }
    if(S[0]+U[0]<=MAX_SIZE){
        //完全插入
        int i,j;
        //1、先往后移
        for(i=S[0];i>=pos;i--){
            //S[i+1]=S[i];//这是往后移一个
            S[i+U[0]]=S[i];//这是往后移T[0]个
        }
        //2、再往里填充
        for(i=pos,j=1;i<pos+U[0];i++,j++){
            S[i]=U[j];
        }
        //3、主串长度改变
        S[0]=S[0]+U[0];
    }else
    {
        //部分插入
        int len,i,j;
        len=MAX_SIZE-S[0];
        for(i=S[0];i>=pos;i--){
            S[i+len]=S[i];
        }
        for(i=pos,j=1;i<pos+len;i++,j++){
            S[i]=U[j];
        }
        S[0]=MAX_SIZE;
    }
    return OK;
}

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

int main()
{
    /*
        S:初始化的主串
        T:复制过来的串
        R:串S和串T连接后的新串
        s:子串
    */
    String 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(S[0]==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");
            Print_String(S);
            break;
        case 11:
            printf("请输入需要删除的起点以及长度(pos,len):");
            scanf("%d,%d",&pos,&len);
            StrDelete(S,pos,len);
            printf("子串删除成功.\n");
            Print_String(S);
            break;
        default:
            printf("输入的序号有误,请重新输入.\n");
            break;
        }
    }
    return 0;
}

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

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

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


  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值