练习2-4 重新编写函数squeeze(s1,s2),将字符串s1中任何与字符串s2中字符匹配的字符都删除。

练习2-4 重新编写函数squeeze(s1,s2),将字符串s1中任何与字符串s2中字符匹配的字符都删除。


参考代码:

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

//void squeeze(char s1[], char s2[])
//{
//    int i = 0;
//    int j = 0;
//    int n = 0;
//    int t;  //表示s1与s2的元素是否相同,1为相同,0为不同
//    while(s1[i] != '\0')
//    {
//        t = 0;
//        j = 0;
//        while(s2[j] != '\0')
//        {
//            if(s1[i] == s2[j])
//                t = 1;
//            j++;
//        }
//        if(t == 0)
//            s1[n++] = s1[i];
//        i++;
//    }
//    s1[n] = '\0';
//}

void squeeze(char s1[], char s2[])
{
    int i, j, k;
    for(i = k =0; s1[i] != '\0'; i++)
    {
        for(j = 0; s2[j] != '\0' && s2[j] != s1[i]; j++)
            ;
        if(s2[j] == '\0')
            s1[k++] = s1[i];
    }
    s1[k] = '\0';
}
int main()
{
    char s1[] = "abgghcbd";
    char s2[] = "bcd";
    squeeze(s1,s2);
    printf("%s", s1);
    return 0;
}

在参考代码中,被注释掉的部分是我自己编写的sequeeze函数,下边的是答案给出的函数,之所以将我自己写的代码注释掉,是因为我觉得答案给出的for循环更加紧凑,for循环更加适合初始化和增加步长都是单条语句且逻辑相关的情形,将循环控制语句都集中放在了一起,因此显得更加紧凑。

具体来说,两个sequeeze函数的思想基本是一样的:在遍历s1的过程中,寻找s2中是否有和s1相同的元素。在我自己写的函数中,设置了变量t来标记是否出现过相同的元素,循环一直到s2的结尾,如果遇到了和s1相同的元素则设置为1,;而在答案给出的函数中,在循环控制的条件中,如果遇到相同元素或者遍历到s2的结尾,则停止循环,如果最后s2遍历到了结尾\0的位置,则表示没有遇到相同的元素;循环结束以后,两个函数的处理是一样的,在我自己写的函数中,如果t为0,则将当前s1[i]覆盖到s1[n]的位置上,然后n++;答案给出的函数中,如果遍历到了结尾,则将s1[i]覆盖到s1[k]的位置上,然后k++;用这种覆盖的方式将和s2中重复的元素删除掉。

解释完过程以后,可以说一下,之所以保留答案给出的函数,最重要的一点就是答案给出的函数执行效率更高,因为在内嵌的循环中,我自己写的函数每次都需要遍历到s2的结尾,而答案的效率提高在于它不需要每次到遍历到s2的结尾,当遇到重复元素时,循环就会停止。因此,相比来说,答案的思路更加值得借鉴。当然,也可以在我的循环中加上t==1这个结束条件,只不过为了对比明显,发现自己的问题,就不作更改了。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值