是自己写的,测评已通过,可能有漏洞或者可简化的地方,多多指教!
串替换
不调用库函数,自己实现字符串替换操作,函数原型为:
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;
}