《算法零基础100讲》(第6讲) 日期算法

1185. 一周中的第几天

在这里插入图片描述
Constraints:

The given dates are valid dates between the years 1971 and 2100.

分析:

  1. 题目给定的年份范围是[1971,2100],然后我们可以根据力扣的数据测试得出1971年1月1日是Friday,当然不嫌麻烦的话也可以去查日历。
  2. 既然知道初始条件,那目前最简单暴力的方法就是直接计算他们相差有多少天。
  3. 因为一周的周期为七天,所以要计算出这一天是一周的第几天我们只需计算 daycnt % 7,但又因为因为初始日期是Friday,所以daycnt的初始条件是4。

代码如下:

char Week[7][10] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

char * dayOfTheWeek(int day, int month, int year){
	//daycnt的初始条件
    int cnt = 4;
    //记录每月的天数
    int Month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    for(int y = 1971; y < year; y++){
    	//判断是否为闰年
        if(y % 100 != 0 && y % 4 == 0 || y % 400 == 0)
            cnt+=366;
        else
            cnt+=365;
    }
    for(int i = 1; i < month; i++){
        //判断2月的天数
        if(i == 2){
            if(year % 100 != 0 && year % 4 == 0 || year % 400 == 0)
                cnt += 29;
            else
                cnt+=Month[i];
        }
        else
            cnt+=Month[i];
    }
    cnt+=day;
    cnt%=7;

    return Week[cnt];
}

1154. 一年中的第几天

在这里插入图片描述
在这里插入图片描述
这道题相对上题较为简单,只需计算本年的天数,唯一难受的地方就是他给的是字符串,但将字符串转化为整型数据的问题已经有人帮我们解决了,所以我们只需拿来用就行,atoi()函数是一个将表示数字的字符串转化为整型数据的一个函数,转化之后一切都简单起来了。

代码如下:

int dayOfYear(char * date){
    int daycnt = 0;
    int year, month, day;
    int Month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    char* str = (char*)malloc(12);
    //转化年份
    strcpy(str, date);
    str[4] = '\0';
    year = atoi(str);
	//转化月份
    strcpy(str, date + 5);
    str[2] = '\0';
    month = atoi(str);
	//转化日期
    strcpy(str, date + 8);
    day = atoi(str);
	//计算天数
    for(int i = 1; i < month; i++){
        if(i == 2){
            if(year % 100 != 0 && year % 4 == 0 || year % 400 == 0)
                daycnt += 29;
            else
                daycnt += Month[i];
        }
        else
            daycnt += Month[i];
    }
    daycnt += day;
    return daycnt;
}

1360. 日期之间隔几天

在这里插入图片描述
这道题我首先用的是暴力的解法,但是有位数学大佬用Zeller公式对这道题进行了解答,这种解法写出的代码十分简便,所以我很推荐这种写法,大家可以去看看他的解析(绝对不是偷懒,只是因为我的解法太low了)。

数学大佬的解法

代码:

int toDay(const char* dateStr) {
    int year, month, day;
    sscanf(dateStr, "%d-%d-%d", &year, &month, &day);
    if (month <= 2) {
        year--;
        month += 10;
    }
    else month -= 2;
    return 365 * year + year / 4 - year / 100 + year / 400
         + 30 * month + (3 * month - 1) / 5 + day /* -584418 */;
}
int daysBetweenDates(char * date1, char * date2){
    return abs(toDay(date1) - toDay(date2));
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

友人苏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值