电子科技大学icoding数据结构-串替换

是自己写的,测评已通过,可能有漏洞或者可简化的地方,多多指教!

串替换

不调用库函数,自己实现字符串替换操作,函数原型为:

int str_replace(const char *in, char *out, int outlen, const char *oldstr, const char *newstr);

参数说明:

  • in, 原始字符串,保持不变
  • out, 存放替换结果的字符串
  • outlen,out空间的大小
  • oldstr,要替换的旧字符串
  • newstr,替换成的新字符串
  • 函数返回成功替换的次数,即有多少个子串被成功替换
     

在替换过程中,任何情况下所得字符串(及结束符)不应该超过 outlen,如果某次替换所得字符串的长度超过 outlen,则不进行这次替换操作,整个替换操作结束。如:
原始串为 "aaabbbccc",outlen 为14, oldstr 为 "c",newstr 为 "333" 时,两次替换后得 "aaabbb333333c",此时字符串占用空间为14字节。
如果再进行替换,则会超出 out 所占用的空间,所以停止替换操作。此时函数应该返回 2, out指向的串为 "aaabbb333333c"
再如:原始串为 "aaabbbccc",outlen 为10, oldstr 为 "b",newstr 为 "123456",进行替换后所得的串长度为14,与结束符一共占 15 个字节,超过outlen的10字节,此时不进行替换,函数应该返回 0。

这个版本的代码不好:(

//:(
int str_replace(const char *in, char *out, int outlen, const char *oldstr, const char *newstr){
    int k=0,a,b,len;
    for(a=0;oldstr[a]!='\0';a++);
    for(b=0;newstr[b]!='\0';b++);
    for(len=0;in[len]!='\0';len++);
    for(int i=0;in[i]!='\0'&&len+k*(b-a)<outlen;){//先计算能够进行几次替换
        int m,j;
        for(m=i,j=0;in[m]==oldstr[j]&&j!=a;j++,m++);
        if(j==a&&len+(k+1)*(b-a)<outlen){//若能完全匹配oldstr且替换后长度不超过outlen,k++;
            k++;
            i=m; //i递增,等效于i+a
        }
        else i++;
    }
    int pos=0,m,j;
    for(int i=0;i<outlen;i++) out[i]='\0';//初始化字符数组
    int n=0,i=0;
    for(;n<k;){//好抽象的写法,不喜欢while吗?
        j=0;
        for(m=i;in[m]==oldstr[j]&&j!=a;j++,m++);
        if(j==a){//匹配方法同上
            n++;//这一行干什么的?删掉删掉
            i=i+a;
            for(int n=0;n<b;n++) out[pos++]=newstr[n];
        }
        else out[pos++]=in[i++];
    }
    for(;in[i]!='\0';i++)out[pos++]=in[i];
    return k;
}

 以下是改进后的代码:

//这是改进后的代码:)
int str_replace(const char *in, char *out, int outlen, const char *oldstr, const char *newstr){
    //out=(char *)malloc(outlen*sizeof(char));
    int in_len=0,oldstr_len=0,newstr_len=0;
    while(in[in_len]!='\0') in_len++;
    while(oldstr[oldstr_len]!='\0') oldstr_len++;
    while(newstr[newstr_len]!='\0') newstr_len++;
    int num=0;  //记录替换次数
    int i=0,index=0;
    while(in_len+(num+1)*(newstr_len-oldstr_len)<outlen&&i<in_len){//先判断是否还有替换空间
        int k,j;
        for(k=i,j=0;in[k]==oldstr[j]&&j<oldstr_len;j++,k++);
        if(j==oldstr_len){//若完全匹配旧字符,则进行替换,将新字符复制到out
            for(int a=0;a<newstr_len;a++)out[index++]=newstr[a];
            i=k;    //i递增,等效于i+new_len
            num++;
        }
        else{
            out[index++]=in[i++];
        }
    }
    if(i<in_len){//剩余的字符复制过去
        while(i<in_len)out[index++]=in[i++];
    }fegnwei
    out[index]='\0';//封尾
    return num;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值