資源描述:
《用c++編寫計(jì)算日期的函數(shù)》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫(kù)。
1、14.1分解與抽象人類解決復(fù)雜問(wèn)題采用的主要策略是“分而治之”,也就是對(duì)問(wèn)題進(jìn)行分解,然后分別解決各個(gè)子問(wèn)題。著名的計(jì)算機(jī)科學(xué)家Parnas認(rèn)為,巧妙的分解系統(tǒng)可以有效地系統(tǒng)的狀態(tài)空間,降低軟件系統(tǒng)的復(fù)雜性所帶來(lái)的影響。對(duì)于復(fù)雜的軟件系統(tǒng),可以逐個(gè)將它分解為越來(lái)越小的組成部分,直至不能分解為止。這樣在小的分解層次上,人就很容易理解并實(shí)現(xiàn)了。當(dāng)所有小的問(wèn)題解決完畢,整個(gè)大的系統(tǒng)也就解決完畢了。在分解過(guò)程中會(huì)分解出很多類似的小問(wèn)題,他們的解決方式是一樣的,因而可以把這些小問(wèn)題,抽象出來(lái),只需要給出一個(gè)實(shí)現(xiàn)即可,凡是需要用到該問(wèn)題時(shí)直接使用即可。案例日期運(yùn)算給定日期由年、月、
2、日(三個(gè)整數(shù),年的取值在1970-2050之間)組成,完成以下功能:(1)判斷給定日期的合法性;(2)計(jì)算兩個(gè)日期相差的天數(shù);(3)計(jì)算一個(gè)日期加上一個(gè)整數(shù)后對(duì)應(yīng)的日期;(4)計(jì)算一個(gè)日期減去一個(gè)整數(shù)后對(duì)應(yīng)的日期;(5)計(jì)算一個(gè)日期是星期幾。針對(duì)這個(gè)問(wèn)題,很自然想到本例分解為5個(gè)模塊,如圖14.1所示。圖14.1日期計(jì)算功能分解圖仔細(xì)分析每一個(gè)模塊的功能的具體流程:1.判斷給定日期的合法性:首先判斷給定年份是否位于1970到2050之間。然后判斷給定月份是否在1到12之間。最后判定日的合法性。判定日的合法性與月份有關(guān),還涉及到閏年問(wèn)題。當(dāng)月份為1、3、5、7、8、10、
3、12時(shí),日的有效范圍為1到31;當(dāng)月份為4、6、9、11時(shí),日的有效范圍為1到30;當(dāng)月份為2時(shí),若年為閏年,日的有效范圍為1到29;當(dāng)月份為2時(shí),若年不為閏年,日的有效范圍為1到28。圖14.2日期合法性判定盒圖判斷日期合法性要要用到判斷年份是否為閏年,在圖14.2中并未給出實(shí)現(xiàn)方法,在圖14.3中給出。圖14.3閏年判定盒圖2.計(jì)算兩個(gè)日期相差的天數(shù)計(jì)算日期A(yearA、monthA、dayA)和日期B(yearB、monthB、dayB)相差天數(shù),假定A小于B并且A和B不在同一年份,很自然想到把天數(shù)分成3段:2.1A日期到A所在年份12月31日的天數(shù);2.2A之
4、后到B之前的整年的天數(shù)(A、B相鄰年份這部分沒(méi)有);2.3B日期所在年份1月1日到B日期的天數(shù)。圖14.4日期差分段計(jì)算圖若A小于B并且A和B在同一年份,直接在年內(nèi)計(jì)算。2.1和2.3都是計(jì)算年內(nèi)的一段時(shí)間,并且涉及到閏年問(wèn)題。2.2計(jì)算整年比較容易,但是也要涉及到閏年問(wèn)題。這里先不討論具體流程,分析完下面幾個(gè)模塊后再討論。3.計(jì)算一個(gè)日期加上一個(gè)整數(shù)天數(shù)后對(duì)應(yīng)的日期計(jì)算日期A(yearA、monthA、dayA)加上一個(gè)整數(shù)天數(shù)days對(duì)應(yīng)的日期,若days小于A日期到A所在年份12月31日的天數(shù)則對(duì)應(yīng)結(jié)果日期在本年中計(jì)算,yearA不變。否則yearA加days。若
5、天數(shù)剩下的的部分夠整年(閏年問(wèn)題),則循環(huán)yearA加days;days去掉一年天數(shù);對(duì)days剩下的不夠一年的天數(shù),在該年計(jì)算對(duì)應(yīng)日期。圖14.5日期加整數(shù)分段計(jì)算圖4.計(jì)算一個(gè)日期減去一個(gè)整數(shù)天數(shù)后對(duì)應(yīng)的日期計(jì)算日期A(yearA、monthA、dayA)減去一個(gè)整數(shù)天數(shù)days對(duì)應(yīng)的日期,若days小于A所在年份1月1日到A日期的天數(shù)則對(duì)應(yīng)結(jié)果日期在本年中計(jì)算,yearA不變。否則yearA減1。若days剩下的的部分夠整年(閏年問(wèn)題),則循環(huán)yearA減1;days去掉一年天數(shù);對(duì)days剩下的不夠一年的天數(shù),在該年計(jì)算對(duì)應(yīng)日期。圖14.6日期減整數(shù)分段計(jì)算圖5
6、.計(jì)算一個(gè)日期是星期幾計(jì)算日期A(yearA、monthA、dayA)為星期幾,需要找到一個(gè)參照的日期B,只需要知道日期B為星期幾,然后計(jì)算出A和B相差的天數(shù),就很容易計(jì)算出A為星期幾。此處又需要用到計(jì)算兩個(gè)日期的差。通過(guò)上述分析,發(fā)現(xiàn)到處都在計(jì)算一段日期天數(shù),這種一段日期天數(shù)分為3種:年內(nèi)1月1日到某日期的天數(shù)(年內(nèi)的前半段);年內(nèi)某日期到12月31日的天數(shù)(年內(nèi)的后半段);整年的天數(shù)。只有整年天數(shù)容易計(jì)算,其他兩種較為復(fù)雜,能不能回避呢?對(duì)于日期A和B的差,可以選定日期C(1970年1月1日),計(jì)算C到A的天數(shù)CA,再計(jì)算C到B的天數(shù)CB,則CB減CA為A到B的天數(shù)
7、。而對(duì)C到A,只需要計(jì)算整年(因?yàn)镃為1月1日)加上A的年內(nèi)前半段,C到B同理。這樣就回避掉了計(jì)算年內(nèi)后半段的問(wèn)題。把從選定日期C(1970年1月1日)到某日期A的天數(shù)用函數(shù)dateToDays(A)來(lái)描述,有了該函數(shù),則問(wèn)題2和5都很容易解決了。對(duì)于問(wèn)題3和4,可以把日期A通過(guò)dateToDays函數(shù)轉(zhuǎn)化為天數(shù),再加減一個(gè)整數(shù),變成一個(gè)新的天數(shù),只需要再定義一個(gè)函數(shù)daysToDate(days)把天數(shù)轉(zhuǎn)換為從1970年1月1日經(jīng)過(guò)該天數(shù)對(duì)應(yīng)的日期即可。daysToDate函數(shù)也只需要處理若干整年(因?yàn)閺?970年1月1日起)和結(jié)果年份