自定义函数之整数处理(含特殊测试)

题目描述(时间限制: 1Sec 内存限制: 128MB)
输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写三个函数; ①输入10个数;②进行处理;③输出10个数。
输入
10个整数
输出
整理后的十个数,每个数后跟一个空格(注意最后一个数后也有空格)
样例输入
2 1 3 4 5 6 7 8 10 9
样例输出
1 2 3 4 5 6 7 8 9 10

分析:
对于数组来说,设置Maxnum和Minnum来保存当前最大、最小元素的数组下标(此处强调是保存下标,不是保存元素)。对Maxnum和Minnum的初始化:其初值均保存首元素的下标,用该初值去与后面的元素一一比较,每次比较结束,Maxnum和Minnum均保存当前的最大、最小值的下标。

值得注意的是:若在一次循环中同时确定最大最小值,容易犯下述错误(分别循环确定并互换最终位的话能避免):

#include <stdio.h>
#include <math.h>
int main()
{
    int a[10];
    scanf("%d",&a[0]);
    int Maxnum=0,Minnum=0;
    for(int i=1;i<10;i++){
        scanf("%d",&a[i]);
        if(a[i]>a[Maxnum])
            Maxnum=i;
        else if(a[i]<a[Minnum])
            Minnum=i;
    }
    int temp;
    temp=a[0];
    a[0]=a[Minnum];
    a[Minnum]=temp;
    temp=a[9];
    a[9]=a[Maxnum];
    a[Maxnum]=temp;
    for(int i=0;i<10;i++)
      printf("%d ",a[i]);
    return 0;
}

虽有样例的输出:
样例输出
但对于下述情况(即首元素即为最大或最小情况):
特殊情况
并没有理想的输出。在首元素为最大并且先进行最小元素换到首位置的操作时,首元素(即最大元素)与Minnum下标的元素互换,最大数就换到了其他位置,而此时Maxnum的值仍为0(即指明a[0]为最大值)。这种情况下,再进行最大数与末尾元素互换,会将首元素(此时已经为最小值)与末尾元素互换。最终造成最小值处于末尾,最大值位置不确定的情况。


解决方法:
虽然可以分先后两次,独立的进行最大最小值的确定和调换其最终位置也可以达到预期效果,但其实在前述代码的基础上加一个判定即可:

#include <stdio.h>
#include <math.h>
int main()
{
    int a[10];
    scanf("%d",&a[0]);
    int Maxnum=0,Minnum=0;
    for(int i=1;i<10;i++){
        scanf("%d",&a[i]);
        if(a[i]>a[Maxnum])
            Maxnum=i;
        else if(a[i]<a[Minnum])
            Minnum=i;
    }
    int temp;
    temp=a[0];
    a[0]=a[Minnum];
    a[Minnum]=temp;
    if(Maxnum==0)                  //针对初始时首元素即为最大的情况
        Maxnum=Minnum;             //追溯前一步被最小值换走的“真·最大值”的真实位置,并赋予Maxnum
    temp=a[9];
    a[9]=a[Maxnum];
    a[Maxnum]=temp;
    for(int i=0;i<10;i++)
      printf("%d ",a[i]);
    return 0;
}
PS:在进行完最小值换到首位置(这是前提)后进行判定,if判定是为了追溯被Minnum所指元素换走的“真·最大值”。
    若在判定前先进行的是最大值确定最终位,那if判定时就要追溯被Maxnum所指元素换走的“真·最小值”,之后才能进行最小值确定最终位。

这道题的陷阱在于:
若没有追溯判断,代码编写中先写最小值确定最终位,此时拿最小值打头的序列去测试正确,但用最大值打头的序列(如:10 5 6 8 4 3 1 2 9 7)去测试则错误;相反,先编写最大值确定最终位,拿最大值打头的序列去测试正确,拿最小值打头的序列去测试则错误。


另贴出c含指针的代码(思路相同):

#include <stdio.h>
#include <math.h>
void creat(int *head);
void spsort(int *head);
void put(int *head);
int main()
{
    int a[10];
    creat(a);
    spsort(a);
    put(a);
    return 0;
}
void creat(int *head)
{
    int *p=head;
    for(int i=0; i<10; i++)
        scanf("%d",(p++));
}
void spsort(int *head)
{
    int *Maxnum=head,*Minnum=head,*p=head,temp;
    for(int i=1; i<10; i++)
        if(p[i]>*Maxnum)
            Maxnum=&p[i];
        else if(p[i]<*Minnum)
            Minnum=&p[i];
    temp=*Minnum;
    *Minnum=p[0];
    p[0]=temp;
    if(Maxnum==head) Maxnum=Minnum;
    temp=*Maxnum;
    *Maxnum=p[9];
    p[9]=temp;
}
void put(int *head)
{
    int *p=head;
    for(int i=0; i<10; i++)
        printf("%d ",*(p++));
}

。。
不知道如何结尾,就这样吧?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值