日期之间间隔几天


  • 输入date1 = "2019-06-29", date2 = "2019-06-30"
  • 输出 1
class Solution {
public:
    bool leap_year(int year){
        return (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0);
    }
    int date_to_int(string date){
        int year , month , day;
        sscanf(date.c_str(),"%d-%d-%d",&year,&month,&day);
        int month_length[] = {31,31,28,31,30,31,30,31,31,30,31,30};
        int res = 0;
        while(year != 1971 || month != 1 || day != 1){
            ++res;
            if(--day == 0){
                if(--month == 0){
                    --year;
                }
            }
            if(day == 0){
                day = month_length[month];
                if(month == 2 && leap_year(year)){
                    ++day;
                }
            }
            if(month == 0){
                month = 12;
            }
        }
        return res;
    }
    int daysBetweenDates(string date1, string date2) {
        return abs(date_to_int(date1)-date_to_int(date2));
    }
};

把month_length的12月的31写在0的位置,调用的时候,month[0-11]的顺序,如果31写在最后的话,日期会差一天,具体情况应该和月份有关系,没太深究。注意代码中有一个判断,若month=0则month=12可以很巧妙的吧0位的31对应上。

class Solution {
public:
    int daysBetweenDates(string date1, string date2) {
        return abs(getdate(date1) - getdate(date2));
    }

    int getdate(string date) {
        int x[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
        int y, m, d, ans = 0;
        sscanf(date.c_str(), "%d-%d-%d", &y, &m, &d);
        // 年计算
        for (int i = 1971; i < y; ++i) 
            if (i % 400 == 0 || i % 4 == 0 && i % 100) ans += 366;
        else ans += 365;
        // 月计算
        if (y % 400 == 0 || y % 4 == 0 && y % 100) x[2] = 29;
        for (int i = 1; i < m; ++i) ans += x[i];
        // 天计算
        return ans + d;
    }
};

static int months[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
class Solution {
private:
    bool isLeap(int year) {
        return year % 100 && year % 4 == 0 || year % 400 == 0;
    }
    int getDay(string date) {
        int year, month, day;
        sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day);
        int days = 0;
        for (int y = 1971; y < year; y ++) {
            days += isLeap(y) + 365;
        }
        for (int m = 1; m < month; m ++) {
            if (m == 2) days += isLeap(year) + 28;
            else
                days += months[m];
        }
        return days + day;
    }

从1971开始按年-月-日的顺序来计算,似乎也挺方便的,记录一下。


知识点记录

  • 判断是否是闰年的方法,400年一轮,4年轮(100年不轮)

  • C++运算法的优先级,++,--操作优先级较高的,比==高,在判断里面,先减再判断;

  • C++ string类型和int类型的转换:

    • int i = atoi(str.c_str())
    • int i = std::stoi(str)
    • string s = to_string(i)
  • sscanf和c_str()的组合用法

    • c_str()的返回值类型是const char *类型(同char const *),指向常量的指针,其值理应是个常量,它的值会随着原来声明值的修改而更改,所以一定要使用strcpy()函数 等来操作方法c_str()返回的指针。

    • sscanf(str,%d,&a)
      • 常量指针和指针常量,指向常量的常指针。
      • 常量指针,指针指向的是个常量,即指针的值(地址)是常量,而不是地址指向的值,但指针本身是个变量。
      • //-------常量指针-------
        const int *p1 = &a; //*p1是个常量
        a = 300;     //OK,仍然可以通过原来的声明修改值,
        //*p1 = 56;  //Error,*p1是const int的,不可通过这个指针修改变量的值
        p1 = &b;     //OK,指针还可以指向别处,因为指针只是个变量,可以随意指向;
      • 指针常量,是指本质是一个常量,但是用指针修饰它,指针的地址可以改变,但是它指向的值不可以改变
      • //-------指针常量-------//
        int*  const p2 = &a; //p2是个常量,指向不可改变
        a = 500;     //OK,仍然可以通过原来的声明修改值,
        *p2 = 400;   //OK,指针是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化
        //p2 = &b;     //Error,因为p2是const 指针,因此不能改变p2指向的内容
      • // 
        const int* const p3 = &a;
        //*p3 = 1;    //Error
        //p3 = &b;    //Error
        a = 5000;    //OK,仍然可以通过原来的声明修改值