题目:
输入正整数n(1<n<=10),再输入n个互不相同的整数,将最小值与第一个数交换,最大值与最后一个数交换,然后输出交换后的n个数。
解题思路:
- 定义数组,将n个整数存入数组中。
- 利用循环遍历数组,找出数组中最大元素的下标和最小元素的下标。
- 将最小值与第一个数交换,最大值与最后一个数交换。
- 输出交换后的数。
代码:
注:这是一段存在错误的代码,想直接看完整的正确代码请往下划到代码改进
#include<stdio.h>
#define N 10
void swap(int* a, int* b)//定义两数交换函数
{
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int n;
int a[N] = { };
int i, min = 0, max = 0;
printf("输入正整数n(1<n<=10):");
scanf("%d", &n);
printf("输入%d个互不相同的整数:", n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);//将n个整数存入数组中
for (i = 0; i < n; i++)//找出最大元素下标
if (a[i] > a[max])
max = i;
for (i = 0; i < n; i++)//找出最小元素下标
if (a[i] < a[min])
min = i;
swap(&a[max], &a[n - 1]);//调用函数
swap(&a[min], &a[0]);
for (i = 0; i < n; i++)//输出交换后的数
printf("%d", a[i]);
return 0;
}
运行结果:
代码改进:
作者收到小伙伴的私信说输入3 1 0时输出了错误的结果,也就是如果最小值在数组的最后一项,将得到一个错误结果
我重新看了一遍我的代码,这个小伙伴是对的,我的代码确实有误,这是思维不够严谨导致的
我们跟着错误的代码走一遍流程,先明确为什么代码会出现这样的错误:
我们输入3 1 0,首先,程序找出了最大值下标为0,最小值下标为2
接着,将最大值与最后一个数交换,也就是下标为0的数将与下标为2的数交换,交换的结果是:0 1 3
然后,程序会将最小值与第一个数交换,也就是下标为2的数将与下标为0的数交换,这时候小伙伴们应该已经能发现问题了:在上一轮交换中,最小值0已经从下标为2的位置调换到了下标为0的位置,最小值的位置改变了,所以min中存储的最小值下标2已经失效了,再交换就会导致结果的错误
那么我们应该如何改进代码呢?
在上述错误的代码中,我们是先将最大值下标和最小值下标都找出来之后再交换,这可能导致再第一次交换之后第二次交换的下标失效。所以我们可以调整代码顺序:先找出最大值下标,将最大值与最后一个数交换,接着,再找出最小值下标,将最小值与第一个数交换
调整后的代码如下:
#include <stdio.h>
#define N 10
void swap(int* a, int* b)//定义交换函数
{
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int n;
int a[N] = { };
int i, min = 0, max = 0;
printf("输入正整数n(1<n<=10):");
scanf("%d", &n);
printf("输入%d个互不相同的整数:", n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);//将n个整数存入数组中
for (i = 0; i < n; i++)//找出最大元素下标
if (a[i] > a[max])
max = i;
swap(&a[max], &a[n - 1]);//调用函数
for (i = 0; i < n; i++)//找出最小元素下标
if (a[i] < a[min])
min = i;
swap(&a[min], &a[0]);
for (i = 0; i < n; i++)//输出交换后的数
printf("%d", a[i]);
return 0;
}