乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      [轉(zhuǎn)帖]快速計算某個日期是星期幾的經(jīng)驗公式

       shaobin0604@163.com 2010-05-17

      巧算星期幾

      基姆。拉爾森

      基姆擁有計算機學科的博士學位。他對數(shù)據(jù)庫,算法和數(shù)據(jù)結(jié)構(gòu)有著濃厚的興趣。他的聯(lián)系地址是            (原文

      為丹麥文--譯者注) 31,DK-5270,Odense N,Denmark,或發(fā) E-mail 至 :kslarsen@imada.ou.dk。

      簡介

      布魯斯 施耐爾

      “四,六,九,十一,三十天就齊……”兒歌是這么唱的;或許你也曾經(jīng)掰著手指頭翻來覆去地數(shù),讓趕上單數(shù)的指頭

      代表只有30天的短月吧?這樣的口訣對我們是很管用的(我就是念叨著這首傻乎乎的兒歌長大的),可是電腦就沒有這

      份“靈感”了。當然,我們可以用一大堆IF-THEN-ELSES的語句或幾個CASE來編寫計算程序,讓它計算某個指定日期是

      星期幾。

      不過我更喜歡基姆拉爾森在本月的“算法小徑”中為我們帶來的新技巧,因為他的方法另辟蹊徑,從一個全新的方向著

      手解決日期計算的問題。其實,并沒有什么數(shù)學公式能算出某個指定日期是星期幾,不過我們可以試著拼湊一個,如果

      我們的嘗試成功了,你就能擁有一個易于編程的數(shù)學公式,并能用它自動計算哪天是星期幾了。

      順便說一句,如果你已經(jīng)設(shè)計出更巧妙的算法,或是在已有的方法上有了新突破的話,不妨告訴我,我一定洗耳恭聽。

      我的聯(lián)系方法是schneier@chinet.com,或 者在DJJ編輯部給我留張便條就行。

      你有沒有疑惑過你的電腦怎么就知道今天是星期三呢?就算你的電腦關(guān)機了,你重啟后設(shè)定了新日期,它也能立即知道

      這天是星期幾。

      在你還是個孩子的時候,你可能見過一種紀錄記錄著年,月,日的表格,只要加上幾個數(shù)字,和它相連的另一張表格就

      會告訴你這個日期是星期幾。當然,計算機硬盤的操作系統(tǒng)里也可以加入這樣的計算表。不過有一種簡單的方法可以輕

      松地算出某天是星期幾;而且這個方法只占用很少的內(nèi)存空間,而那些只能推算幾百年的表格可就太占地方了。

      如果目前你的電腦還不具備推算與日期對應(yīng)的星期數(shù)的功能,現(xiàn)在就不妨在自己的程序中試試下面的公式。

      創(chuàng)建公式

      首先,我們要用變量D,M和Y來表示日期。比如,1994年3月1日就用“D=1,M=3,Y=4”記錄。我們的目標是讓計算結(jié)

      果在0到6之間。0代表星期一,1代表星期二,2代表星期三,依此類推。

      1994年3月1日是個星期二,那么“D mod 7(日期變量除以7的余數(shù)))))”這個公式對于整個三月份都有效。比如3月18日

      是星期五,18 mod 7=4;而4正代表星期五。別忘了,整數(shù)的除法和求模有著密切的關(guān)系。比方說,26除以7商3余5,這

      就是說,26除以7商數(shù)取整等于3,而26除以7求模(簡寫為26 mod 7)等于5。以上這些意味著19 mod 7=12 mod 7= 5

      mod 7=5。在運算規(guī)則中,負數(shù)求模運算法相似,所以依此類推,-2 mod 7=5, -9 mod 7=5。

      在更正式的表達法中,統(tǒng)一用任意整數(shù)n和k表達上述關(guān)系,那么這個過程可以表達為n=qk+r,這里的q和r的取值范圍同

      樣是整數(shù)和0。表1中列出了所有月份的變換數(shù)據(jù)(shift information此處試譯為“檔級數(shù)據(jù)”,還請進一步校對--譯

      者注)。為了盡可能地得出規(guī)律,二月被排在最后,同理,一月也是如此。

      例1(a)中的公式是仿照表1中的變換數(shù)據(jù)欄所描述的模式而創(chuàng)建的。這個公式中的除法一律是商數(shù)取整。所以得數(shù)是最

      接近真正商數(shù)的整數(shù)。表2得出了此功能得出的有趣的數(shù)值。憑直覺,我們不難發(fā)現(xiàn),當M(代表月份的變量)的值以1為單

      位遞增時,2M就成倍增長,而3(M+1)/5就以3/5為增長倍數(shù)。

      這正是我們仿制3,2,3,2,3這個重復(fù)格式所需要的(表中右邊的彎括號表明了這一點)。請注意,我們在以7為除數(shù)求模

      ,那么從6到2的求模結(jié)果就會逐個增加3(順序是6,0,1,2)。

      現(xiàn)在,我們發(fā)現(xiàn)了適用于逐月向下推算的校正方法,并希望把它加入剛才的嘗試中,就是那個mod7公式。還以1994年3月

      1日為例,這個日期的M=3。請注意,在例1(b)中,8 mod 7=1,所以當整個公式合并時,必須減去1。在做以7為除數(shù)

      求模的運算時,減1和加6是一樣的,因為-1 mod 7=6 mod 7=6。

      這樣,例1(c)中的公式就可以計算這一年中剩下的月份了。其實,既然我們把一月和二月排在表1的最后,那么只要我

      們把它們看成是十三月和十四月,就能接著推算1995年的前兩個月了。這是因為,雖然它們并不是一個完整的3,2,3,2,3

      結(jié)構(gòu),但恰好可以是這個結(jié)構(gòu)的開始,為了使這個公式更完善,我們還是最好把一月和二月看成是上一年的十三月和十

      四月。

      加入年份

      順著年份向下找,我們觀察到1995年3月1日是星期三。這說明,每增加一年,我們公式的計算結(jié)果就會增加1。這太簡單

      了,我們只要簡單地把年份加上去就行了。再提醒你一次,我們必須確保出發(fā)點是正確的。由于1994 mod 7=6,我們在

      把Y加入已有的公式時就必須減去6。由此改進的例2(a)就更完善了。

      1996年是個閏年,這帶來了我們的下一個問題。這一年的3月1日是星期五,而不是剛才的公式推算出的星期四。所以每

      當我們碰上閏年時還得多加上1。判斷閏年的規(guī)則是,能被4整除,并能被100和400同時整除的年份就是閏年。就這樣,

      我們在原有的基礎(chǔ)上添加Y/4--Y/100+Y/400。再強調(diào)一下,我們必須從一開始就確保正確。既然(1994/4--

      1994/100+1994/400) mod 7=(498--19+4) mod 7=483 mod 7=0,所以就不用再做任何調(diào)整了。這樣,例2(b)就是我們最終

      的成果了。這個公式能一直工作下去,除非改變現(xiàn)行的日歷系統(tǒng)。作為示例,讓我們試著推算一下2000年7月4日:

      (4+2*3+(7+1)/5+2000+2000/4--2000/100+2000/400) mod 7= (4+14+2000+500--20+5) mod 7=2507 mod 7=1,所以那一

      天是星期二。

      這個公式還能推算過去的日期;然而計算范圍有限,讓我們看看1752年9月14號這個星期四吧,我們的公式最遠只能推算

      到這里了。不過像“1963年11月22日你在哪里”這樣的日常問題中提到的日期還是可以輕松應(yīng)對的:(22+2*11+3

      (11+1)/5+1963+1963/4--1963/100+1963/400) mod 7=(22+22+7+1963+490--19+4) mod 7=2489 mod 7=4。那天就是星期

      五。

      例3例子3是一個C語言程序,按照把這個公式自動推算給定日期是星期幾。

      表1:每月變換數(shù)據(jù)

      月份         天數(shù)         變換

      三月          31            3

      四月          30            2

      五月          31            3

      六月          30            2

      七月          31            3

      八月          31            3

      九月          30            2

      十月          31            3

      十一月        30            2

      十二月        31            3

      一月          31            3

      二月          28            3

      表2:仿制變換數(shù)據(jù)形式的功能。例1中建立的公式可以適用于1994年。例2把這個公式的功能擴展到可以應(yīng)用在不同的年

      份進行推算。

      例3:用C語言程序表達上述公式

       

      1. /*一 月和二月被當作前一年的*/  
      2.   
      3. /*十三月和十四月分別處理*/  
      4.   
      5.   
      6. /*計算指定日期是星期幾。默認輸入的*/  
      7.   
      8. /*數(shù)字代表正確的日期*/  
      9.   
      10. /* 推算給定日期是星期幾,假定輸入是正確的數(shù)據(jù) */  
      11. #include   
      12. char *name[] = { "Monday",  
      13.                  "Tuesday",  
      14.                  "Wednesday",  
      15.                  "Thursday",  
      16.                  "Friday",  
      17.                  "Saturday",  
      18.                  "Sunday"  
      19.                };  
      20. void main()  
      21. {  
      22.     int D,M,Y,A;  
      23.     printf("Day: "); fflush(stdout);  
      24.     scanf("%d",&D);  
      25.     printf("Month: "); fflush(stdout);  
      26.     scanf("%d",&M);  
      27.     printf("Year: "); fflush(stdout);  
      28.     scanf("%d",&Y);  
      29.     /* January and February are treated as month 13 and 14*/  
      30.     /* respectively, from the year before.*/  
      31.     if ((M == 1) || (M == 2))  
      32.     {  
      33.         M += 12;  
      34.         Y--;  
      35.     }  
      36.     A = (D + 2*M + 3*(M+1)/5 + Y + Y/4 - Y/100 + Y/400) % 7;  
      37.     printf("It's a %s.\n",name[A]);  
      38. }  
      39.   
      40.    
      41.   
      42.    
      43.   
      44. /*一月和二月被當作前一年的*/  

       

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多