因为每次一到交C语言作业的前一天,就会有好多好多小伙伴过来问我作业上哒题目~
老师平时也很少详细讲解作业上的编程题。
另外,最近也有不少人说希望能够有C语言方面的学习交流平台~
所以我决定在自己的技术博客里持续更新大家问我问的比较多的一些作业里的C语言题目,和一些我认为比较难的C语言题目。博文里会有我的题目分析过程,构思,以及代码~
这个系列的名字就暂定为“C语言小练习”~
不过这些都是我的个人思路,不一定是最好哒,大家可以在评论里提出自己的优化方法或者一些自己不懂的题目或细节~~(≧▽≦)/~
下面是上一次数组的实验报告里小伙伴们问的比较多的题目:
输入10个整数,将这10个整数按升序排列输出,并且奇数在前,偶数在后。比如,如果输入的10个数是1 2 3 4 5 6 7 8 9 10,则输出1 3 5 7 9 2 4 6 8 10。
分析:
我们先对这个题目所要实现的目标进行拆解,那么它可以拆解成这样几个小部分:
1、输入10个整数
2、将十个整数里奇数全部放前面,偶数全部放后面
3、对前面奇数进行升序排列,对后面偶数进行升序排列
4、输出10个整数
现在我们要用数组实现上面四个步骤~首先声明一个数组a[10]。
为了确定奇数和偶数的分界线,我们设定两个计数变量,odd和even分别代表奇数和偶数,在用for循环,循环输入时,每输入一个奇数,odd+1,每输入一个偶数,even+1。
我们就用%2是否==0作为判断奇数和偶数的条件。
这里呢其实odd和even就可以看做是两个指针(虽然他们并不是)。
odd指向数组最右方,给它赋-1,even指向最左方,赋上10
这时我们可以发现,每输入一个奇数,odd+1,指针向右移动一格,odd的值与所指向的元素下标数值一致,even同理。最后输入完成后,odd和even所指元素的中间的分界线就是奇数和偶数的分界线。如图所示(绿色代表输入的数):
接下来我们就想办法实现第二步了,我们可以发现左边的本应该放奇数的位置每放了一个偶数,右边放了偶数的地方就放了一个奇数,那么我只要在左右两边在分别放上i,j两个变量,把他们看做指针,分别遍历左右两边,碰到odd和even就停止。左边每碰到一个偶数,右边每碰到一个奇数,就交换两边的数字。
结束后左边就只有奇数,右边就只有偶数
接下来我们使用选择排序的方法,以分界线为界对左右两边分别排序。即从左往右对所有数遍历,每次将没有遍历的数分别和他后面的所有数比较,一旦遇到后面有比他小的数就交换,这样就可以实现每一次指向的数始终比后面的数小。
最后循环输出全部就行啦~
以下是源代码:
#include<stdio.h>
int main()
{
int i,j,k,t,odd=-1, even=10,a[10];
for(i=0;i<=9;i++) //循环输入并计数
{
scanf("%d",&a[i]);
if(a[i]%2!=0)
odd++;
else
even--;
}
for(i=0;i<=odd;i++) //将奇数放左边,偶数放右边,每次错位就交换
for(j=9;j>=even;j--)
{
if(a[i]%2==0&&a[j]!=0)
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
for(i=0;i<odd;i++) //选择排序左边
for(j=i+1;j<=odd;j++)
if(a[i]>a[j])
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
for(i=even;i<9;i++) //选择排序右边
for(j=i+1;j<=9;j++)
if(a[i]>a[j])
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
printf("\n排列:\n"); //循环输出
for(i=0;i<=9;i++)
printf("%d ",a[i]);
return 0;
}