当前位置:   article > 正文

程序员的算法趣题--入门篇(c++描述)日期的二进制转换_二进制日期

二进制日期

问题描述:

  把年月日表示为 YYYYMMDD 这样的 8 位整数,然后把这个整数转换成 二进制数并且逆序排列,再把得到的二进制数转换成十进制数,求与原日期一 致的日期。求得的日期要在上一次东京奥运会(1964 年 10 月 10 日)到下一 次东京奥运会(预定举办日期为 2020 年 7 月 24 日)之间。

例)日期为1966年7月13日时 ① YYYYMMDD格式→ 19660713 ② 转换成二进制数→ 1001010111111111110101001 ③ 逆序排列→ 1001010111111111110101001 ④ 把逆序排列得到的二进制数转换成十进制数→ 19660713

分析:

  处理日期多麻烦哦,我们交给库函数处理,嘿嘿。剩下的我们需要考虑怎样优化算法。先看时间转化为二进制的范围196410101001010111111111110101001‬,20200724→‭1001101000011110100010100‬。可以看到二进制前4位是一样的,所以后面的四位也需要是1001。即我们所需要的十进制数字满足:(dec - 9 )%16 == 0 -----(1),这里我们需要分两种情况考虑:

  • 当前日期加上16时年月不变,这时我们可以直接用之前的日期十进制数加上16作为下个十进制数,而不需要再次转化。
  • 当前日期加上16年或月变化,这时我们需要将当前的日期日期重置1,重新寻找满足等式(1)的十进制数字。

代码实现:

#include <time.h>
#include <vector>
using std::vector;
int toDec (const tm & cur_date);
void getNext (tm* cur_date);
void searchStart(int encoded, tm* start_date);
int main() {
    struct tm start_date = {0};
    vector <tm> res;
    start_date.tm_mday = 1;start_date.tm_year = 70;start_date.tm_mon = 0;//mktime is available after 1970.
    int encoded = toDec(start_date);
    searchStart(encoded, &start_date);
    while (encoded <= 20200724){
        int p_end = 0x00000010, p_begin = 0x00100000;
        while (p_end != p_begin){
            if ((bool)(p_begin & encoded) == (bool)(p_end & encoded)){//detect one bit. remember transform to bool.
                p_begin = p_begin >> 1;
                p_end = p_end << 1;
            }else{
                break;
            }
        }
        if (p_end == p_begin)
            res.push_back(start_date);
        getNext(&start_date);
        encoded = toDec(start_date);
    }
    printf("palindromic date has been listed as follow \n");
    for (const auto i : res){
        printf("%s\n", asctime(&i));
    }
    return 0;
}
void getNext (tm* cur_date){
    cur_date->tm_mday += 16;
    int pre_mon = cur_date->tm_mon;
    mktime(cur_date);
    if (cur_date->tm_mon != pre_mon){
        cur_date->tm_mday = 1;
        searchStart(toDec(*cur_date), cur_date);
    }//turn to next month.
}
int toDec (const struct tm & cur_date){
    int encodeed = (cur_date.tm_year + 1900)*10000 + (cur_date.tm_mon + 1)*100
                   + cur_date.tm_mday;//Be careful the rule of date.
    return encodeed;
}
void searchStart(int encoded, tm* start_date){
    const int p = 0x0000000f;
    while((encoded & p) != 0x00000009) {
        encoded++;
        start_date->tm_mday++;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

这里顺便总结一下头文件time.h的一些常用日期处理用法(具体参见c++ reference):

在这里插入图片描述

time_t mktime (struct tm * timeptr);//将创建的tm转换为time_t,time_t是time_ptr所指向的对象与19700101相差的秒数,该过程
与localtime正相反。且将日期转换为合理的格式,例如20190435会被更改为20190505。
  • 1
  • 2
struct tm * localtime (const time_t * timer);//将时间转换为本地时间
  • 1
char* asctime (const struct tm * timeptr);//返回表示时间的字符串形如:Www Mmm dd hh:mm:ss yyyy
  • 1

值得一提的是,C /C++用 32 位的二进制数来表示以 1970 年 1 月 1 日为起点的时间,这也是上述程序以1970为起点的原因所在,如果向mktime传递的时间小于1970年,则会得到-1,所以如果处理1970年以前的时间则需要另谋他法。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/766458
推荐阅读
相关标签
  

闽ICP备14008679号