题解 | #删除元素#
删除元素
https://ac.nowcoder.com/acm/problem/22228
这道题目我的思路直来直去,原本的代码是这样的:
```#include <stdio.h>
int main()
{
int n,m,j;
while(scanf("%d\n",&n)!=EOF)//多组输入,牛客上面都是这样写的
{
int a[n];
for(int i=0;i<n;i++) scanf("%d ",&a[i]);
scanf("%d\n",&m);//前三行按规定输入
for(j=0;j<n;j++)
{
if(a[j]==m)//遍历数组,如果找到m,则执行下面代码;否则应该是j一直加到n跳出循环,证明原数组里面找不到m
{
if(j<n-1)//找到m的时候,如果不是数组末尾
{
for(j=j;j<n-1;j++)
{
a[j]=a[j+1];
}
//将所有后续数组全部覆盖修改,最后一次执行是把a[n-1]赋给前一位,
//这样变化后的新数组相当于是删掉了第一次出现m的那个元素,末尾元素不变
for(int i=0;i<n-1;i++) printf("%d ",a[i]);
printf("\n");
return 0;//将变化后的新数组只输出0到n-2,不输出末尾的a[n-1],符合题目要求。
}
else for(int i=0;i<n-1;i++) printf("%d ",a[i]);
printf("\n");
return 0;//如果第一次找到m就是数组末尾,那么只需要输出除去末尾的前面所有项,
}
}
if (j==n) for(int i=0;i<n;i++) printf("%d ",a[i]);
printf("\n");//如果原数组中找不到m,那么只要把原数组再输出即可。
}
return 0;
}
这个代码经过多次自我检测,对于单组输入没有任何问题,但是提交之后发现只能通过20%测试样例。经过我反复检查,发现问题出现在循环跳出上。在我的代码块中,一旦完成输出,我不能只采用break跳出循环,因为那样只是跳出了最内层,外层循环还会继续进行,这显然不符合题意,于是我才用了return 0;但是return 0会跳出所有循环直达主函数结束,这样会导致最外层用来保证多组输入的while循环也被跳出。那么怎么解决这个问题呢,这里我也希望有更多大佬能够答疑解惑。我最后不得不采用goto语句,使其不是跳出所有循环而是跳转到循环开始进行下一组输入,总算是AC了。修改后的代码如下(其实就是把return0改成了goto):
```#include <stdio.h>
int main()
{
int n,m,j;
loop: while(scanf("%d\n",&n)!=EOF)//多组输入,牛客上面都是这样写的
{
int a[n];
for(int i=0;i<n;i++) scanf("%d ",&a[i]);
scanf("%d\n",&m);//前三行按规定输入
for(j=0;j<n;j++)
{
if(a[j]==m)//遍历数组,如果找到m,则执行下面代码;否则应该是j一直加到n跳出循环,证明原数组里面找不到m
{
if(j<n-1)//找到m的时候,如果不是数组末尾
{
for(j=j;j<n-1;j++)
{
a[j]=a[j+1];
}
//将所有后续数组全部覆盖修改,最后一次执行是把a[n-1]赋给前一位,
//这样变化后的新数组相当于是删掉了第一次出现m的那个元素,末尾元素不变
for(int i=0;i<n-1;i++) printf("%d ",a[i]);
printf("\n");
goto loop;//将变化后的新数组只输出0到n-2,不输出末尾的a[n-1],符合题目要求。
}
else for(int i=0;i<n-1;i++) printf("%d ",a[i]);
printf("\n");
goto loop;//如果第一次找到m就是数组末尾,那么只需要输出除去末尾的前面所有项,
}
}
if (j==n) for(int i=0;i<n;i++) printf("%d ",a[i]);
printf("\n");//如果原数组中找不到m,那么只要把原数组再输出即可。
goto loop;
}
return 0;
}