串的基本操作(C语言实现)

在这里我们采用定长顺序存储表示(不知道也没关系)
在C语言中以’\0’表示串的终结,此时串长为隐藏值,不方便进行某些串操作。所以,这里我们用第一个数组来存储长度。
&表示引用不知道也没关系

StrAssign(&T,chars)
初始条件:char是字符串常量
操作结构:生成一个值为chars的串T
代码:

#include<stdio.h>
#include<stdlib.h>
#define MAXSTRLEN 100 //用户可在100以内定义最大长度

union SString  //因为第一个数组存储长度的原因,这里使用了共用体
{              //有兴趣的小伙伴可以直接定义字符数组试试
    int len;
    char ch;
};
void StrAssign(union SString *T,char *chars)
{
    int i=0;
    while (*(chars+i) != '\0' && i<MAXSTRLEN)
    {
        T[i+1].ch = *(chars+i);  //T[0]用于存储串的长度,所有T[i+1]
        ++i;
    }
    T[0].len = i;         //i为整型,得用对应的类型存储,不然会很麻烦
}

int main()
{
    union SString T[MAXSTRLEN+1]; //零单元存放串的长度
    StrAssign(T,"hello world!");
    for (int i=0;i<T[0].len;++i)
    {
        printf("%c",T[i+1].ch);
    }


    printf("\n串的长度为:%d",T[0].len);
    return 0;
}

运行结果:
在这里插入图片描述
main函数中的是用来测试用的,下面将不再给出全部代码及运行结果,仅给出相关函数

StrCopy(&T,S)
初始条件:串S存在
操作结果:由串S复制得串T
代码:

void StrCopy(union SString *T,union SString *S)
{
    for (int i=0;i<S[0].len && i<MAXSTRLEN;++i)
    {
        T[i+1].ch= S[i+1].ch;   //一一修改
    }
    T[0].len = S[0].len;     //更新串T的长度
}

StrEmpty(S)
初始条件:串S存在
操作结果:串S为空返回True(1) 否则false(0)
代码:

int StrEmpty(union SString *T)
{
    if (T.len == 0) return 1;
    return 0;
}

StrCompare(S,T)
初始条件: 串S,T均存在
操作结果:如果 S>T 返回值>0 如果S<T 返回值<0 否则返回值=0
代码:

int Strcompare(union SString *T,union SString *S)
{
    for (int i=0;i<T[0].len && i<S[0].len;++i)
    {
        if (T[i+1].ch == S[i+1].ch) ++i;   //相等则同时后移
        else if (T[i+1].ch > S[i+1].ch) return 1;  //T>S
        else return 0;  //T<S
    }
}

StrLength(S)
初始条件:串S存在
操作结果:返回S的长度
代码:

int StrLength(union SString *T)
{
    return T[0].len;
}

ClearString(&S)
初始条件:串S存在
操作结果:将串S清为空串
代码:

void ClearStr(union SString *T)
{
    for (int i=0;i<T[0].len;++i)
    {
        T[i+1].ch = '\0';
    }
    T[0].len=0;
}

Concat(&T,S1,S2)
初始条件: 串S1,S2均存在存在
操作结果:用T返回由S1,S2连接而成的新串
代码:

void Concat(union SString *T,union SString *S1,union SString *S2)
{//T的值有三种情况
    int i,label;   //label用于标记
    if (S1[0].len+S2[0].len <= MAXSTRLEN)       //第一种情况 未截断
    {
        for (i=0;i<S1[0].len;++i)   //复制S1
        {
            T[i+1].ch = S1[i+1].ch;
        }
        for (;i<S2[0].len;++i)   //复制S2
        {
            T[i+1].ch = S2[i+1].ch;
        }
        T[0].len = S1[0].len+S2[0].len;  //更新T的长度
        label = 1;
    }
    else if (S1[0].len<MAXSTRLEN)    //第二种情况 截断   (S1[0].len+S2[0].len > MAXSTRLEN)
    {
        for (i=0;i<S1[0].len;++i)   //复制S1
        {
            T[i+1].ch = S1[i+1].ch;
        }
        for (;i<MAXSTRLEN;++i)   //复制S2 条件和上一种情况不一样
        {
            T[i+1].ch = S2[i+1].ch;
        }
        T[0].len = MAXSTRLEN;  //更新T的长度
        label=0;
    }
    else   //第三种情况 截断   (仅截取S1)  (S1[0].len==MAXSTRLEN)
    {
        for (i=0;i<S1[0].len;++i)   //复制S1
        {
            T[i+1].ch = S1[i+1].ch;
        }
        T[0].len = MAXSTRLEN;  //更新T的长度
        label=0;
    }
    return label;
}

SubString(&Sub,S,ps,length)
初始条件:串S存在,1<=pos<=StrLength(S) 且0<=length<=StrLength(S)-pos+1
操作结果:用Sub返回串S的第pos字符起长度为len的子串
代码:

void SubString(union SString *Sub,union SString *S,int pos,int length)
{
    if (pos < 1 || pos > S[0].len || length < 0 || length >S[0].len-pos+1)
    //说一下S[0].len-pos+1 
    //如有串’abcde’  pos=1 则5-pos=4 因为是从pos开始 故还要加上1
    {
        printf("请输入正确的值")return;
    }
    for (int i=0;i<length;++i)
    {
        Sub[i+1].ch = S[pos-1+1+i].ch;  //pos-1是为了对应下标,加1是因为第一个位置存储串的长度
    }
    Sub[0].len = len;
}

Index(S,T,pos)
初始条件:串S和T存在,T是非空串,1<=pos<=StrLength(S)
操作结果:返回子串T在主串S中第pos个字符之后第一次出现的位置,若不存在则返回数值0。
代码:

int Idex(union SString *T,union SString *S,int pos)
{
    int i,j,label=0;
    if (pos < 1 || pos > S[0].len)
    {
        printf("请输入正确的值")return label;
    }
    for (i=pos-1;i<S[0].len;++i)  //pos-1对应数组下标
    {
        j = i;
        while (S[j+1].ch == T[j+1].ch && j<S[0].len && i-j<T[0].len)
        {
            j++;
        }
        if (j-i == T[0].len) //j-i为上一个循环执行的次数
        {
            label=i+1;
            break;
        }
    }
    return label;
}

StrInsert(&S,pos,T)
初始条件:串S,T均存在1<=pos<=StrLength(S)+1
操作结果:在串S的第pos个字符前插入串T
代码:

void StrInsert(union SString *S,int pos,union SString *T)
{
    int i;
    if (pos < 1 || pos > S[0].len+1)
    {
        printf("输入的值不合法!\n");
        return;
    }
    for (i=S[0].len;i>=pos;--i)       //未插入T而腾出空间
    {
        S[i+T[0].len].ch = S[i].ch;
    }
    for (i=pos;i-pos<T[0].len;++i)    //插入
    {
        S[i].ch = T[i-pos+1].ch;
    }
    S[0].len+=T[0].len; //更新S的长度
}

StrDelete(&S,pos,len)
初始条件:串S存在1<=pos<=StrLength(S)-len+1
操作结果:删除串S的第pos字符起长度为len的子串
代码:

void StrDelete(union SString *S,int pos,int len)
{
    int i;
    if (pos < 1 || pos > S[0].len-len+1)  //pos > S[0].len-len+1 即 len > S[0].len-pos+1 
    {                                    //两数相减得的是其距离,因为从pos起,所以+1
        printf("输入的值不合法!\n");
        return;
    }
    for (i=pos;i-pos<len;++i)  //i-pos<len+1 让其循环len次;
    {
        S[i].ch = S[i+len].ch;   //直接覆盖
    }
    S[0].len -= len;
}

DestroyString(&S)
初始条件:串S存在
操作结果:串S被销毁
代码:
用堆分配存储表示的时候再写

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值