有一天,我漫不经心的为C语言考试备考,看到小伙伴给我发来这样一道题:
从键盘上输入两组整数,每组包含5个整数,使第一组整数按照从大到小的顺序排列,第二组按照从小到大顺序排列。
很简单对吧,反正也不会什么高级的排序,那就冒泡排序吧,我那么懒,就想着直接写一个冒泡排序,再复制一遍不就行了,于是我的代码是这样的:
#include<stdio.h>
int main()
{
int i,j,t;
int a[5],b[5];
for(i=0;i<=4;i++)
{
scanf("%d",&a[i]); //输入第1个数组
}
for(i=0;i<=4;i++)
{
scanf("%d",&b[i]); //输入第2个数组
}
//int a[5]={1,2,3,4,5}; //这是为了调试查看方便而直接赋值的
//int b[5]={1,2,3,4,5};
for(i=0;i<5;i++) // 第2次冒泡
for(j=0;j<5;j++)
{
if(a[j]<a[j+1]) //升序交换
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
for(i=0;i<5;i++) //第二次冒泡
for(j=0;j<5;j++)
{
if(b[j]>b[j+1])
{
t=b[j]; // 降序交换
b[j]=b[j+1];
b[j+1]=t;
}
}
for(i=0;i<5;i++)
printf("%d ",a[i]); //输出第一个数组
printf("\n");
for(i=0;i<5;i++)
printf("%d ",b[i]); // 输出第二个数组(错的)
// printf("%d ",b[i+1]); //输出第二个数组(对的)
return 0;
}
看似毫无问题吧,除了在for循环里多排了几遍。
(因为我懒得去记怎么优化,反正就这几个数还是没问题的)。
可是在输出时却遇到了问题,如图,b在递增里,原本应该是1 2 3 4 5的,却变成了0 1 2 3 4
冒泡错.png
我猜着去把printf("%d ",b[i]);换成了printf("%d ",b[i+1]);
没想到这样却可以正常输出了,变成了我想要的:
5 4 3 2 1
1 2 3 4 5
讲道理不管是输入还是输出,我的数组b都是从0开始的,而我赋值时,b[0]就是1呀。
于是我在循环前输出了b[0],输出结果的确是1
可是循环之后就变成了0,那就说明是循环的问题,可是循环里,我又重新使i,j归零了呀。
我就干脆多输出了几组循环之后 b的相关数据:
b[0]==0, b[-1]==0 ,b[6]越界,输出地址,i==5.找不到问题所在
带着这个疑惑,我请教了木子。他说冒泡这里好像有个什么问题,要是他就不会定义两个数组,而是再把第一个数组覆盖掉,再录入一遍。
....
似乎并没有少那么几行代码...
这是他的思路:
#include<stdio.h>
int main()
{
int i,j,t;
int a[5];
for(i=0;i<=4;i++)
{
scanf("%d",&a[i]); //录入数组元素 5 个
}
for(i=0;i<5;i++) //第一次冒泡
for(j=0;j<5;j++)
{
if(a[j]<a[j+1]) //这是降序
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
for(i=0;i<5;i++)
printf("%d ",a[i]); //输出降序
printf("\n");
for(i=0;i<=4;i++)
{
scanf("%d",&a[i]); //覆盖输入
}
for(i=0;i<5;i++) //第二次冒泡
for(j=0;j<5;j++)
{
if(a[j]>a[j+1]) //升序
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
for(i=0;i<5;i++)
printf("%d ",a[i]); //输出
return 0;
}
当然,从功能上是没问题的,除了有那么一点点的不合题目规定,但是凭什么他的这样就没有问题。
于是我找到了社长请教,我们听听社长怎么说
网友评论