機試演算法講解: 第3題 求兩個日期相差的天數
阿新 • • 發佈:2019-01-31
/* 問題:求兩個日期相差的天數,連續2天預設為一天。日期形式:YYYYMMDD 輸入: 20110412 20110422 輸出: 11 思路:方法1:將2個日期都應該化為絕對秒數,然後相減,用絕對秒數之差然後除以24*3600即可 易錯點: time_t mktime(struct tm* tmptr) double difftime(time_t time1,time_t time2) char* strncpy(char* strDest,const char* stdSource,size_t count)返回的是strDest void* memset(void* dest,int i,size_t count) 方法2: 建立一個日期結構體,判斷閏年:能被4整除且不能被100整除,或者能被400整除, 建立月份:1,3,5,7,8,10,12有31天 4,6,9,11有30天 2月:閏年29天,平年28天 if( (i/4==0 && i/100!=0) || i/400==0 ) 20140122 19891005 8875(正確) 8870錯誤 年與年相減得diffYear,每一年按照是否是閏年加366或365 小日期的月做減法:依次減去上一個的天數 大日期的月做加法: 依次加上上一個月的天數 小日期的日做減法:依次減去日期 大日期的日做加法:依次加上日期 易錯點: 1結構體內不能給陣列賦值 2採用加減法計算日期,不需要最終再加上1 3while(scanf("%4d%2d%2d",&y1,&m1,&d1)) 來讀取前4位給年,後2位給月 */ #include <stdio.h> #include <string.h> #include <time.h> #include <memory.h> //memset #include <stdlib.h> //atoi //#define leap(y) ((y/4==0 && y/100!=0) || y/400==0),寫錯了是%而不是/ #define leap(y) ((y%4==0 && y%100!=0) || y%400==0) typedef struct Date { bool operator < (Date& date) { if(iYear != date.iYear) { return iYear < date.iYear; } else { if(iMon != date.iMon) { return iMon < date.iMon; } else { return iDay < date.iDay; } } } void operator = (Date& date) { iYear = date.iYear; iMon = date.iMon; iDay = date.iDay; } //int iMonArr[2][12] = { {0,31,28,31,,30,31,30,31,31,30,31,30},{0,31,29,31,30,31,30,31,31,30,31,30} };//用兩個花括號括起來,結構體內不能賦值 int iYear; int iMon; int iDay; }Date; void toDate(char* sDate,Date& date) { char sStr[4]; memset(sStr,0,4); strncpy(sStr,sDate,4); //Date date; date.iYear = atoi(sStr); memset(sStr,0,4); strncpy(sStr,sDate+4,2); date.iMon = atoi(sStr); memset(sStr,0,4); strncpy(sStr,sDate+6,2); date.iDay = atoi(sStr); //return date; } int Days(Date& date1,Date& date2) { int iMonArr[2][13] = { {0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31} }; Date dateMax; Date dateMin; if(date2 < date1) { dateMax = date1; dateMin = date2; } else { dateMax = date2; dateMin = date1; } int iDiffDays = 0,i; for( i = dateMin.iYear ; i < dateMax.iYear ; i++ ) { iDiffDays += leap(i) ? 366:365; } for( i = 1 ; i < dateMax.iMon ; i++) { //iDiffDays += iMonArr[leap(dateMax.iYear)][i-1]; iDiffDays += iMonArr[leap(dateMax.iYear)][i]; } //iDiffDays += dateMax.iDay ; iDiffDays += dateMax.iDay -1; for( i = 1 ; i < dateMin.iMon ; i++) { //iDiffDays -= iMonArr[leap(dateMax.iYear)][i-1]; iDiffDays -= iMonArr[leap(dateMax.iYear)][i];//已經沒有取當前月的天數了 } //iDiffDays -= dateMin.iDay; iDiffDays -= dateMin.iDay -1; //return(iDiffDays+1);//這裡不需要加1,因為求出來的就是兩天之差 return iDiffDays; } //using namespace std; time_t mk_time(char* sDate) { struct tm tTm; char sStr[4]; //memset(sStr,0,4); //memset(tTm,0,sizeof(tm)); memset(&tTm,0,sizeof(tTm)); memset(&sStr,0,4); tTm.tm_year = atoi(strncpy(sStr,sDate,4)) - 1900; memset(&sStr,0,4); tTm.tm_mon = atoi(strncpy(sStr,sDate+4,2)) - 1; memset(&sStr,0,4); tTm.tm_mday = atoi(strncpy(sStr,sDate+6,2)) + 1;//連續2天算兩天之差 return mktime(&tTm); } int main(int argc,char* argv[]) { //char sDate1[9]; //char sDate2[9]; Date date1,date2; //int y1,m1,d1,y2,m2,d2; //while(EOF!=scanf("%s %s",sDate1,sDate2)) while(EOF!=scanf("%4d%2d%2d",&date1.iYear,&date1.iMon,&date1.iDay)) { scanf("%4d%2d%2d",&date2.iYear,&date2.iMon,&date2.iDay); //time_t tTime1 = mk_time(sDate1); //time_t tTime2 = mk_time(sDate2); //time_t diffTime = (time_t)difftime(tTime1,tTime2); //int iDays = (int)( diffTime > 0 ? diffTime/(3600*24) : (-1)*diffTime/(3600*24) ); //printf("%d",iDays); //Date date1,date2; //toDate(sDate1,date1); //toDate(sDate2,date2); int iDays = Days(date1,date2); printf("%d",iDays); } getchar(); return 0; }