日期類(lèi):
一、例2.3 求兩個(gè)日期間的天數(shù)差;區(qū)間問(wèn)題:統(tǒng)一區(qū)間
自己的寫(xiě)法 思路/錯(cuò)誤:
1)統(tǒng)一到0000年01月01日,分別計(jì)算相差天數(shù),再相減+1;在讀取輸入的字符串時(shí)用的gets() 但無(wú)法使用string類(lèi)的substr方法提取部分字符串,進(jìn)而無(wú)法用atof轉(zhuǎn)換為數(shù)值型
2)參考書(shū)上給的示例,發(fā)現(xiàn)讀取時(shí)可以直接用%4d%2d%2d來(lái)讀取特定位數(shù)的數(shù)字;1)中計(jì)算year1和year2之前的年份天數(shù)時(shí)有誤,只判斷year1或year2是不是閏年,未計(jì)算之前的年份;2)中沒(méi)有考慮相差天數(shù)的正負(fù)問(wèn)題,應(yīng)在計(jì)算中加ABS絕對(duì)值;3)表示平常年份和閏年的兩組天數(shù)應(yīng)為days[13][2], 其中0月有0天{0,0}
3)重新統(tǒng)一區(qū)間,統(tǒng)一到更小年份如year1的year10101,計(jì)算更簡(jiǎn)便;增加islonger()函數(shù)和ABS()函數(shù);判斷閏年出錯(cuò)(x%100!=0&&x&4==0||x%400=0?1:0)
參考示例 精妙之處:
1)定義一個(gè)宏來(lái)判斷是否是閏年 #define ISYEAP(x) x%100!=0&&x%4==0||x$400==0?1:0
2)根據(jù)普通年和閏年2月天數(shù)區(qū)分 定義一個(gè)二維數(shù)組 存儲(chǔ)每月天數(shù)的數(shù)組 dayOfMonth[13][2]
3) 使用三維數(shù)組,用年、月、日分別表示數(shù)組下標(biāo),buf[5001][13][32], 定義為全局變量,以免內(nèi)存不足
4)輸入格式巧妙%4d%2d%2d
5) 以00000101為原點(diǎn)時(shí)間,預(yù)處理所有日期(0000-5000)與原點(diǎn)日期之間的天數(shù)差并保存,當(dāng)控制臺(tái)真正輸入數(shù)據(jù)時(shí),只需要O(1)的時(shí)間復(fù)雜度將保存的數(shù)據(jù)做差值處理即可,空間換時(shí)間。
6)直接用dayOfMonth[Month][ISYEAR(Year)]來(lái)調(diào)用每月天數(shù),注意ISYEAR()的bool值正好與0/1對(duì)應(yīng)
7)定義一個(gè)Date結(jié)構(gòu) 和 結(jié)構(gòu)內(nèi)的nextDay()方法 循環(huán)計(jì)算天數(shù)!
二、例2.4? 輸入日期,輸出該日期為星期幾
自己的寫(xiě)法 思路/錯(cuò)誤:
1)寫(xiě)兩個(gè)struct結(jié)構(gòu)數(shù)組,將month.name和month.num;week.name和week.num對(duì)應(yīng)起來(lái);復(fù)習(xí)了結(jié)構(gòu)數(shù)組的初始化 (其實(shí)和普通數(shù)組一樣 {{},{},...{}}; 不懂為什么書(shū)上可以直接換行表示不用{} 是版本問(wèn)題嗎?
2)以今天日期的星期數(shù)為參照(2018.6.10 星期天)計(jì)算任一天與今天的相差天數(shù) 再%7;若為正數(shù) 則直接可對(duì)應(yīng);若為負(fù)數(shù),則需+7再對(duì)應(yīng);其中Sunday在正數(shù)時(shí)為0 在負(fù)數(shù)時(shí)為7 故week結(jié)構(gòu)中賦值有兩個(gè)Sunday
3)給字符串變量賦值用到了strcpy(str1,str2) 將str2賦值給str1 不能直接用=
4)主要的錯(cuò)誤集中在:stack overflow 在buf的定義中以為只要1000-3000的year就可以定義為2001了 然而實(shí)際上最大的還是buf[3000] 所以如果要減小空間 需要buf[i-1000] 但是為了可讀性和簡(jiǎn)便 就沒(méi)有那么做了; 此外 注意strcmp函數(shù)=0時(shí)是相等 不要弄反了
5)關(guān)于string和string.h:string.h是C的頭文件,包括strcpy/strcat等字符串處理函數(shù);string是C++的標(biāo)準(zhǔn)頭文件,包括string類(lèi)和C中的string.h
參考示例 學(xué)習(xí)之處:
1)對(duì)于month.name和month.num以及week.name和week.num的處理沒(méi)有用到struct結(jié)構(gòu)數(shù)組,而只用普通數(shù)組,月名可以與下標(biāo)對(duì)應(yīng),更簡(jiǎn)單!即monthname[num]=name
2) 在比較輸入的字符串和初始化的月名的循環(huán)中,用到了break,可以減少循環(huán)次數(shù)
3)對(duì)于間隔天數(shù)正負(fù)的處理:沒(méi)有像我一樣分開(kāi)處理,而是統(tǒng)一用(interval%7+7)%7 也可以達(dá)到效果,更簡(jiǎn)便
4)輸出字符串用到了puts,比較一下puts和printf的區(qū)別:puts相當(dāng)于printf("%s\n",s)