吉林大学 程序设计基础 2022级 实验复盘 11.10

本人能力有限,发出只为帮助有需要的人。

以下为实验课的复盘,内容会有大量失真,请多多包涵。

1.一周中的下一个热天(填空)

向一个长度为7的数组中输入七天的气温(范围为-10到+10)

找到每天以后更热(温度大于此天)的一天,输出其间隔的天数

样例(题目所给样例忘了,这个是新编的)

输入1 1 -1 2 3 1 4

输出3 2 1 1 2 1 0

原题如下

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int temperature[7],i,j;
    for(i=0;i<7;i++)
        scanf("%d",&temperature[i]);
    int days[7]={0};
    for(i=0;i<7;i++)
    /*
    
    */
    for(i=0;i<7;i++)
        printf("%d ",days[i]);
    return 0;
}

解答

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int temperature[7],i,j;
    for(i=0;i<7;i++)
        scanf("%d",&temperature[i]);
    int days[7]={0};//考了数组初始化,但对此题的作答无影响
    for(i=0;i<7;i++)
    {
        int flag=0;
        for(j=i+1;j<7;j++)//两层循环
        {
            flag++;
            if(temperature[j]>temperature[i])
            {
                days[i]=flag;//构建新数组
                break;
            }
        }
    }
    for(i=0;i<7;i++)
        printf("%d ",days[i]);
    return 0;
}

2.删除数组中的多余元素

输入正整数n,并输入一个长度为n的数组(n<10000),保证数组顺序排序,所有数使用int即可

先输出剩余元素个数,并输出各个元素,要求每个元素占用四个字节,并且右对齐。

样例

输入:9 -1 -1 0 1 1 2 4 4 4

输出:空空空5空空-1空空空0空空空1空空空2空空空4(空代表空格)

#include <stdio.h>
int main(void)
{
    int a[10001],n,k,i,j;
    scanf("%d",&n);
    a[n]=100000;//考试时就折在这上面
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(i=0;i<n-1;i++)
    {
        j=i+1;//此题的数组输入是递增的所以可以减少一次循环
        while(a[j]==a[i])
        {
            for(k=j;k<n;k++)//将a[j]删除,之后的元素前提
                a[k]=a[k+1];
            n--;
        }
    }
    printf("%4d",n);
    for(i=0;i<n;i++)
        printf("%4d",a[i]);
}

这题考试的时候有一个点没过去,显示程序异常应该就是进入了死循环

后来测试的时候才测出来,末尾输入元素都为0时有小概率会死循环(当所有元素都为0时一定出现)

原理是此题删除元素的操作导致最后一个数会赋值为内存中原有的值

开数组时有一定概率使得内存中的a[n]=a[n-1](a[n]未曾赋值),进而使得循环无法跳出

而当元素全为零时,内存中会大概率出现的a[n]=a[n-1]=0的情况,导致程序出错

当然解决方法就是将a[n]赋值为具体的一个数,这样就不会出现此bug

这种比较隐形的bug的确很难在短时间内找出来,要注意没有赋值过的数组元素不要参与程序运算。

另一种方法(此种明显简单,也是之前作业中写过的方法)

#include <stdio.h>
int main()
{
    int n,a[100],i,j,flag=0;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(i=0;i<n-1;i++)
    {
        j=i+1;
        while(a[j]==a[i]&&a[i]!=-100)//注意要排除连续相同的情况
        {
            flag++;//flag为重复元素个数
            a[j]=-100;//将重复元素赋值成一个不常用的数
            j++;
        }
    }
    printf("%4d",n-flag);
    for(i=0;i<n;i++)
    {
        if(a[i]!=-100)//输出不重复的元素
            printf("%4d",a[i]);
    }
}

3.给年月输出日

当年份小于等于0,或月份不合法时,输出年 月 erro

样例:

输入:2022 2

输出:28

输入:2000 13

输出 :2000 13 erro

#include <stdio.h>
int main()
{
    int a,b,c;
    scanf("%d %d",&a,&b);
    if(a<=0||b<1||b>12)
        printf("%d %d erro",a,b);
    else if((a%4==0&&a%100!=0)||a%400==0)
    {
        switch(b)
        {
            case 2:printf("29");break;
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:printf("31");break;
            default:printf("30");break;
        }
    }
    else
    {
       switch(b)
        {
            case 2:printf("28");break;
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:printf("31");break;
            default:printf("30");break;
        }
    }
    return 0;
}

4.含羞草问题(和11.3实验相同)

#include <stdio.h>
int main()
{
    int x,i=0,j;
    scanf("%d",&x);
    for(j=0;j<500;j++)
    {
        x+=i;
        i+=2;
        while(x>31)//此处很多人会写x%=31,但这样很难避免出现x==0的情况,导致点过不去。
            x-=31;
        printf("%3d",x);
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈驰水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值