国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

codeup 1928 日期差值

2019-11-11 03:05:03
字體:
來源:轉載
供稿:網友

日期處理問題真是讓人感到頭疼,需要非常細心的去處理細節。(但是看了《算法筆記》上的解法,我覺得方法才是最重要的……)

下面以codeup上的一道題來介紹相關問題,以及從中習得的一些新的知識點。題目如下:

題目描述有兩個日期,求兩個日期之間的天數,如果兩個日期是連續的我們規定他們之間的天數為兩天。輸入有多組數據,每組數據有兩行,分別表示兩個日期,形式為YYYYMMDD輸出每組數據輸出一行,即日期差值樣例輸入2013010120130105樣例輸出5

非常常規的一道題目,驗證了“細節處理非常重要”這句話,但是更加驗證了“方法更重要”這句話。

題目分析

首先,分析一下這個題目。我們需要做的事情有如下:1. 處理日期的輸入2. 如何計算兩個日期的差值

處理日期的輸入

我的方法

我想到的是用之前剛剛學會的sscanf 來處理輸入,如下:

char time1[10],time2[10];scanf("%s",time1);scanf("%s",time2);int year1,month1,day1;int year2,month2,day2;sscanf(time1,"%4d%2d%2d",&year1,&month1,&day1);sscanf(time2,"%4d%2d%2d",&year2,&month2,&day2);

這種方法乍一看是可以的,不過事實上也的確可以。我們獲取輸入的目的無非就是想要把年、月、日拿出來,而這種方法已經達到了這樣的一個目的。

不過為了而后面的程序,我們必須把time1和time2分出個大小來,而這種拿法剛開始我認為在比較time1和time2大小上非常麻煩,需要有很多的分支判斷。再寫這篇文章的時候才猛然醒悟,類比后面的方法,此處的比較大下可以直接用串比較函數(strcmp函數)進行比較即可,親測可行。

《算法筆記》處理輸入的方法

下面給出《算法筆記》上處理輸入的方法,自己沒想到上面所說的字符串比較方法之前,覺得這個方法真實無比的巧妙??!代碼如下:

int time1, time2; //time1存小時間,time2存大時間int year1,month1,day1, year2,month2,day2;scanf("%d%d",&time1, &time2) if(time1 > time2){//保證time1存小時間,time2存大時間 int temp = time1; time1 = time2; time2 = temp; } // 除法(10^(n+1))拿到前面的n位數,模拿到后面n位數 year1 = time1/10000; month1 = time1%10000/100; day1 = time1%100; year2 = time2/10000; month2 = time2%10000/100; day2 = time2%100;

從代碼可以看出,直接用兩個整形變量拿到time1和time2,之后用除法和取模運算,拿到相應的位數。

經過反思,我發現我之所以沒有想到這種方法,根本原因是在于對除法和取模運算的本質掌握不夠透徹,從這里得出一個結論:

結論:除法和取模運算可以用來獲取一個整形數的對應的位數,且存在如下規律:- 若想獲取整數X的前N位,則用X/10(N+1)- 若想獲得整數X的后N位,則用X%10(N+1)

這么一來,這兩種方法可以說是殊途同歸了,關鍵點還是回到了如何計算兩年的時間差。

計算日期的差值

我的想法

首先是我自己的第一想法,比如輸入為20160328和20110118這兩個日期,我的想法是分成三部分進行計算,總天數 = 20120101-20160101這一大塊時間 + 20160101-20160328這段時間 + 20110118-20111231這段時間,這種方法需要考慮的細節特別多,毫無意外我敗了……

后來想到的方法是用一個“標志時間”,比如說19700101,然后分別計算輸入的兩個日期距離這個“標志時間”的天數x和y,最后結果就是x-y(或者其他的關系,總值是兩個距離的差值,相信讀者能懂)。這個方法沒有去實現,因為我看了下面的方法,真是太神奇,太巧妙了!不過也僅僅是按照“實際情況”而已。

《算法筆記》計算兩日期差值的方法

正如前一段的最后一句話,《算法筆記》中的方法僅僅是按照時間遞進的“實際情況”來進行模擬而已。(我想,這也是為什么晴神把日期問題放在第三章入門模擬的原因吧……)

什么叫做“按照時間遞進的實際情況”呢?就是從曉得日期time1一天一天的過到time2,也許說的不夠明白,下面請看代碼:

int sum = 1;//初始值為1而不是0while(year1<year2 || month1<month2 || day1<day2){ day1++; if(day1 > monthNum[month1][isLeapYear(year1)]){ month1++; day1 = 1;//注意點 } if(month1 > 12){ year1++; month1 = 1;//注意點 } sum++;}

相信看到代碼就能夠理解上面的感悟了。

其中,isLeapYear()是一個判斷是否是閏年的函數bool isLeapYear(int year){ return ( (year%4 == 0 && year%100 != 0) || (year % 400 == 0) );}monthNum是一個數組int monthNum[13][2] = {{0,0}, {31,31}, {28,29}, {31,31}, {30,30}, {31,31}, {30,30}, {31,31}, {31,31}, {30,30}, {31,31}, {30,30}, {31,31} };

這個方法所有的巧妙之處幾乎都體現在上面這兩段代碼中,請讀者自行體會其中的精妙。

完整代碼

#include<stdio.h>bool isLeapYear(int year);int monthNum[13][2] = {{0,0}, {31,31}, {28,29}, {31,31}, {30,30}, {31,31}, {30,30}, {31,31}, {31,31}, {30,30}, {31,31}, {30,30}, {31,31} }; int main(){ int time1, time2; //time1存小時間,time2存大時間 int year1,month1,day1, year2,month2,day2; while(scanf("%d%d",&time1, &time2) != EOF) { if(time1 > time2){ int temp = time1; time1 = time2; time2 = temp; } // 除法(10^(x+1))拿到前面的x位數,模拿到后面x位數 year1 = time1/10000; month1 = time1%10000/100; day1 = time1%100; year2 = time2/10000; month2 = time2%10000/100; day2 = time2%100; int sum = 1; while(year1<year2 || month1<month2 || day1<day2){ day1++; if(day1 > monthNum[month1][isLeapYear(year1)]){ month1++; day1 = 1; } if(month1 > 12){ year1++; month1 = 1; } sum++; }

《算法筆記》購買地址。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 棋牌| 伊春市| 浮山县| 兴山县| 宜川县| 安西县| 萍乡市| 垫江县| 称多县| 揭东县| 昂仁县| 深州市| 小金县| 西昌市| 汤原县| 游戏| 明光市| 古田县| 阳曲县| 云南省| 莱阳市| 阿勒泰市| 道孚县| 美姑县| 恩平市| 化德县| 晋城| 双城市| 彩票| 南丰县| 永修县| 新和县| 黎城县| 隆子县| 郧西县| 且末县| 吉木萨尔县| 萨迦县| 安乡县| 锦屏县| 九龙县|