老师帮瞅瞅有没优化的地方 是否太麻烦了 但是这也是我目前唯一能想到的思路了哈哈

老师帮瞅瞅有没优化的地方 是否太麻烦了 但是这也是我目前唯一能想到的思路了哈哈

https://img1.sycdn.imooc.com//climg/64d0cb2f099dde8400000000.jpg

问题描述:调试了好久终于实现了  大概思路 创建年月日星期结构体 在做一个日期的映射表 
以今天日期2023 8 7 周一 为标准 如果输入日期比今天早 那么今天的日期不断减1天直到
等于输入日期  如果输入日期比今天日期晚 今天的日期一直加1  所以要创建一个加一和减一
的方法 然后循环调用直到标准日期等于输入日期 感觉是不是太麻烦了 
老师帮看看有没有优化的思路啥的
#include<string.h>
#include<stdio.h>
#include<malloc.h>
// 星期的映射表
char *weeks[7] = {"SUN","MON", "TUE", "WED", "THU", "FRI", "SAT" };
// 每月天数 默认是平年
int month_day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
typedef struct
{
    int year;
    char month;
    char day;
    char week;
} date;
// 将输入的年月日 创建结构体
date *create_date()
{
    date *date1 = (date *)malloc(sizeof(date));
    printf("please input [year month day]:");
    scanf("%d %d %d", &date1->year, &date1->month, &date1->day);
    return date1;
}
// 判断平闰年方法
int is_leap(date *para)
{
    int i = 0;
    if (para->year % 400 == 0 || (para->year % 4 == 0 && para->year % 100))
    {
        i = 1;
    }
    return i;
}

// 当前日期减一天的计算逻辑
date *sub_day_1(date *date1)
{

    date1->week--;
    if (date1->week == -1)
    {
        date1->week = 6;
    }
    date1->day--;
    // 情况1 1月1日
    if (date1->day == 0 && date1->month == 1)
    {
        date1->day = 31;
        date1->month = 12;
        date1->year--;
    }
    // 情况2  3月一日 需要判断今年是闰年还是平年
    else if (date1->day == 0 && date1->month == 3)
    {
        if (is_leap(date1))
        {
            date1->day = 29;
        }
        else
        {
            date1->day = 28;
        }
        date1->month = 2;
    }
    // 情况三 其他月份一日
    else if (date1->day == 0)
    {
        date1->month--;
        date1->day = month_day[date1->month - 1];
    }

    return date1;
}
// 当前日期加一天的计算逻辑
date *add_day_1(date *date1)
{

    date1->week++;
    if (date1->week == 7)
    {
        date1->week = 0;
    }
    date1->day++;
    // 情况1 12月31日
    if (date1->month == 12 && date1->day == 32)
    {
        date1->day = 1;
        date1->month = 1;
        date1->year++;
    }
    // 情况2  2月28日 需要判断今年是闰年还是平年
    else if (date1->day == 29 && date1->month == 2)
    {
        if (is_leap(date1))
        {
            date1->day = 29;
        }
        else
        {
            date1->day = 1;
            date1->month = 3;
        }
    }
    // 情况三 其他月份最后一天
    else if (date1->day > month_day[date1->month - 1])
    {
        date1->month++;
        date1->day = 1;
    }

    return date1;
}

// 计算给定年月日的星期
void week(date *date1)
{
    date temp = {2023, 8, 7, 1};
    int a = date1->year * 10000 + date1->month * 100 + date1->day;
    int b = temp.year * 10000 + temp.month * 100 + temp.day;
    if (a > b) // 输入日期比模板日期大
    {
        while (temp.year != date1->year || temp.month != date1->month || temp.day != date1->day)
        {

            add_day_1(&temp);
        }
    }
    else // 输入日期比模板日期小
    {
        while (temp.year != date1->year || temp.month != date1->month || temp.day != date1->day)
        {

            sub_day_1(&temp);
        }
    }

    date1->week = temp.week;
    printf("%d-%d-%d is %s", date1->year, date1->month, date1->day, weeks[date1->week]);
}

// 计算该天是这一年第几天 逻辑就是不断减一天 减到1月1日停止
void day(date *date1)
{
    int i = 1;
    date temp = *date1;

    while (temp.day != 1 || temp.month != 1)
    {
        sub_day_1(&temp);
        i++;
    }

    printf("%d-%d-%d is %d day of the year\n", date1->year, date1->month, date1->day, i);
}
// 根据日期创建日历表 只显示当月的 日和星期
void Calendar(date *para)
{
    int cal_max; // 传入日期当月的天数
                 // 判断闰年还是平年
    if (is_leap(para))
    {
        month_day[1] = 29;
    }
    cal_max = month_day[para->month - 1];
    int number = 1; // 往日历表填数的起始天数 后续一次递增

    date temp = {2023, 8, 7, 1};                    // 参考日期标准
    date para_coppy = {para->year, para->month, 1}; // 定义一个 月首结构
    date *para_1 = &para_coppy;

    int a = para_1->year * 10000 + para_1->month * 100 + para_1->day;
    int b = temp.year * 10000 + temp.month * 100 + temp.day;
    if (a > b) // 输入日期比模板日期大
    {
        while (temp.year != para_1->year || temp.month != para_1->month || temp.day != para_1->day)
        {

            add_day_1(&temp);
        }
    }
    else // 输入日期比模板日期小
    {
        while (temp.year != para_1->year || temp.month != para_1->month || temp.day != para_1->day)
        {

            sub_day_1(&temp);
        }
    }

    para_1->week = temp.week; // 拿到了传参日期当前月第一天的 星期数
    // 构建二维数组 日历表
    int table[5][8];
    for (int i = 0; i < 6; i++)
    {
        for (int j = 0; j < 7; j++)
        {
            if (i == 0 && j < para_1->week % 7)
            {
                table[i][j] = 0;
            }
            else if (number <= cal_max)
            {
                table[i][j] = number;
                number++;
            }
            else
                table[i][j] = 0;
        }
    }
    // 输出日历结果
    printf("\t%d year %d month\n", para->year, para->month);
    for (int i = 0; i < 7; i++)
    {
        printf("%s\t", weeks[i]);
    }
    printf("\n");
    // 打印前面 还有后面的空格

    for (int i = 0; i < 6; i++)
    {
        for (int j = 0; j < 7; j++)
        {
            if (table[i][j] == 0)
            {
                printf("\t");
            }
            else
            {
                printf("%d\t", table[i][j]);
            }
        }
        printf("\n");
    }
}

int main()
{
    date *d = create_date();
    if (is_leap(d))
    {
        printf("%d-%d-%d is leap year\n", d->year, d->month, d->day);
    }
    else
        printf("%d-%d-%d is not leap year\n", d->year, d->month, d->day);
    day(d);
    week(d);
    Calendar(d);
    free(d);
    return 0;
}


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
中年猿叔 2023-08-08 07:30:15
整体思路还是很不错的,Calendar函数太长了,可以在封装几个小函数,增加代码的可读性,加油!
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师