【1185】一周中的第几天

场景:

题目:一周中的第几天
(1)需求:给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天;输入为三个整数:day、month 和 year,分别表示日、月、年。您返回的结果必须是这几个值中的一个 {“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”}。
(2)示例:
示例 1:
输入:day = 31, month = 8, year = 2019
输出:“Saturday”
(3)提示:
给出的日期一定是在 1971 到 2100 年之间的有效日期;


思路:

(1)提示:了解年月日的基本信息,详见扩展;
(2)确定当前年是闰年还是非闰年(闰年可以整除4并且100或者整除400),闰年366天,非闰年365天;
(3)确定二月天数:闰年29天,非闰年28天;
(4)有效日期区间是 [1971-2100],为了在计算天数中确定闰年或非闰年,选取1970作为参照年,1970-01-01为参照日期,求传入的日期到参照日期之间的总天数;
(5)确定月数组:月输入范围为1-12,因此巧妙的将数组中下标为0的元素设置为0,下标为1的元素才是第一个月的天数;
(6)确定周数组:1970-01-01是周四,数组中存储着一周中的七天,总天数days初始化为0,那么当days = 1时,表示这一天是周四,即days = 0时表示周三,根据这一特性,巧妙的设置周数组将周三作为下标为0的元素,weeks[days%7]就可以很好的确定是周几;
(7)这个巧妙的方法来源于官方题解下一位名为 lion-girl 的用户;


扩展:

(1)一个月有28、29、30、31天;
(2)一月、三月、五月、七月、八月、十月、十二月这七个月是31天;
(3)四月、六月、九月、十一月这四个月是30天;
(4)二月的闰年是29天,非闰年是28天;
(5)农历就是阴历,阳历就是公历;

代码实现:

#include <string>
#include <sstream>
using namespace std;
class Solution
{
public:
    string dayOfTheWeek(int day, int month, int year)
    {
        int daysOfMonth[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        string weeks[] = {"Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday"};
        // 求一年中天数
        int days = 0;
        for (int y = 1970; y < year; y++)
        {
            days += isRun(y) ? 366 : 365;
        }
        // 更新一年中二月天数
        if (isRun(year))
        {
            daysOfMonth[2] = 29;
        }
        // 求总天数
        for (int m = 1; m < month; m++)
        {
            // 1970-01-01 + 1971-xx
            days += daysOfMonth[m];
        }
        // 1970-01-01 + 1971-xx-xx
        days += day;
        // 一周中的第几天
        return weeks[days % 7];
    }

private:
    // 是否闰年 (闰年 366天、非闰年365天)
    bool isRun(int year)
    {
        return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    }
};
上一篇:datetime -- timedelta


下一篇:面向对象程序设计——继承