1.题目

输入2个字符串S1和S2,要求删除字符串S1中出现的所有子串S2,即结果字符串中不能包含S2。

输入格式:

输入在2行中分别给出不超过80个字符长度的、以回车结束的2个非空字符串,对应S1和S2。

输出格式:

在一行中输出删除字符串S1中出现的所有子串S2后的结果字符串。

输入样例:
Tomcat is a male ccatat
cat
输出样例:
Tom is a male

(样例male后有空格!!)

2.分析

暴力解法:逐个字符筛查,相同的字符串删掉

3.代码

第一次尝试:while循环条件设置不当,S1的更新不恰当

#include <stdio.h>
int main()
{
    char S1[80],S2[80];
    int Len_1=-1,Len_2=-1,i,j,count=0,flag=0;  
    do{                 //输入S1的数据
        Len_1++;
        scanf("%c",&S1[Len_1]);
    }while(S1[Len_1]!='\n');
    
    do{                  //输入S2的数据
        Len_2++;
        scanf("%c",&S2[Len_2]);
    }while(S1[Len_2]!='\n');
    
    while()
    {
      for(i=0;i<Len_1;i++)
      {
            if(S1[i]=='0')      //已经遍历过
                continue;
        if(S1[i]!=' '&&S1[i]==S2[0])   //S1某个不为空格的字母与S2的第一个相同时
        {
           for(j=0;j<Len_2;j++)
           {
               S1[i+j]=S2[j];
               count++;
           }
           
           if(count==Len_2)    //S1连续字符与S2相同
           {
               for(;i<i+Len_2;i++)  //将相同的标记为’0‘
                   S1[i]='1';
               flag=1;   //标记有重复的
           }
       }
          
      }
    }

    for(i=0;i<Len_1;i++)
        if(S1[i]!='1')        //不为0字符的时候打印
            printf("%c",S1[i]);
    
    return 0;
}

7-29 删除字符串中的子串_i++

第二次:应该将删除空格的情况考虑进去

#include <stdio.h>
int main()
{
    char S1[80], S2[80];
    int Len_1 = -1, Len_2 = -1, i, j, k, count = 0, flag = 0;
    do {                 //输入S1的数据
        Len_1++;
        scanf("%c", &S1[Len_1]);
    } while (S1[Len_1] != '\n');

    do {                  //输入S2的数据
        Len_2++;
        scanf("%c", &S2[Len_2]);
    } while (S2[Len_2] != '\n');

    do
    {
        flag = 0;
        for (i = 0; i < Len_1; i++)
        {
            if (S1[i] != ' ' && S1[i] == S2[0])   //S1某个不为空格的字母与S2的第一个相同时
            {
                count = 0;
                for (j = 0; j < Len_2; j++)
                {
                    if (S1[i + j] == S2[j])
                        count++;
                }

                if (count == Len_2)    //S1连续字符与S2相同
                {
                    if (Len_1 - i > Len_2)   //后面大于Len_2个长度
                    {
                        for (k = i; k < Len_1 - Len_2; k++)  //将与S2相同的覆盖
                            S1[k] = S1[k + Len_2];
                    }

                    Len_1 -= Len_2;   //更新Len_1的长度
                    flag = 1;   //标记经过上述for循环操作
                }
            }
        }

    } while (flag == 1);

    for (i = 0; i < Len_1; i++)
            printf("%c", S1[i]);

    return 0;
}

7-29 删除字符串中的子串_i++_02
并未通过测试点3:
错误如下:

if (S1[i] != ' ' && S1[i] == S2[0])   //S1某个不为空格的字母与S2的第一个相同时

S1[i]是可以为’ '的,擅自将此情况排除出去,引起错误

尝试3:正确解法✔

#include <stdio.h>
int main()
{
    char S1[80], S2[80];
    int Len_1 = -1, Len_2 = -1, i, j, k, count = 0, flag = 0;
    do {                 //输入S1的数据
        Len_1++;
        scanf("%c", &S1[Len_1]);
    } while (S1[Len_1] != '\n');

    do {                  //输入S2的数据
        Len_2++;
        scanf("%c", &S2[Len_2]);
    } while (S2[Len_2] != '\n');

    do
    {
        flag = 0;
        for (i = 0; i < Len_1; i++)
        {
            if (S1[i] == S2[0])   //S1与S2的第一个字母相同时
            {
                count = 0;
                for (j = 0; j < Len_2; j++)
                {
                    if (S1[i + j] == S2[j])
                        count++;
                }

                if (count == Len_2)    //S1连续字符与S2相同
                {
                    if (Len_1 - i > Len_2)   //后面大于Len_2个长度
                    {
                        for (k = i; k < Len_1 - Len_2; k++)  //将与S2相同的覆盖
                            S1[k] = S1[k + Len_2];
                    }

                    Len_1 -= Len_2;   //更新Len_1的长度
                    flag = 1;   //标记经过上述for循环操作
                }
            }
        }

    } while (flag == 1);

    for (i = 0; i < Len_1; i++)
            printf("%c", S1[i]);

    return 0;
}

7-29 删除字符串中的子串_c语言_03

4.总结

做此题用了3h左右,总的来说还是实现的思路不清晰

5.更新日志

2022.3.17 整理(C)

(应该有库函数可以直接使用来优化解法,后续学习会更新用库函数的方法)

记得私信提醒更新~~