练习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这个结束条件,只不过为了对比明显,发现自己的问题,就不作更改了。

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/taolusi/article/details/52386401
个人分类: C
上一篇练习2-3 编写函数htoi(s),把由16进制数字组成的字符串(包含可选的前缀0X或0x)转换成与之等价的整形值。字符串中允许包含的数字包括:0 ~ 9, a ~ f,A ~ F。
下一篇练习2-5 编写函数any(s1,s2),将字符串s2中的任一字符在字符串s1中第一次出现的位置作为结果返回。如果s1中不包含s2的字符,则返回-1。
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭