2013-01-23 100 views
0

我有下面的函數,如果傳入的參數是一個合理的日期,它應該返回true,否則返回false。問題在於即使對於明顯合理的日期它也會返回錯誤,我無法弄清楚它有什麼問題。眼睛更銳利的人請幫助。這裏是:我的函數有什麼問題

fun reasonable_date(x: int*int*int) = 
    if #1 x > 0 andalso #2 x > 0 andalso #2 x <= 12 andalso #3 x > 0 andalso #3 x <= 31 
    then         
    if #2 x = 1 mod 2 andalso #2 x < 8 andalso #3 x <= 31 then true 
     else if #2 x = 0 mod 2 andalso #2 x >= 8 andalso #3 x <= 31 
     then true 
    else if #2 x = 0 mod 2 andalso #2 x < 8 
    then 
     if #2 x = 2 andalso (#3 x = 28 orelse #3 x = 29) then true 
     else if #2 x = 0 mod 2 andalso #3 x <= 30 then true 
     else false 
     else if #2 x = 1 mod 2 andalso #2 x > 8 andalso #3 x <=30 then true 
    else false 
    else false 
+0

待辦事項你的意思是它總是返回false,或者它返回一些錯誤,但不是所有的合理日期? –

+2

你可能會考慮用適當的'andalso'或'orelse'來替換一些'if-then-else'表達式。目前情況相當混亂。 –

+0

它總是返回false。但現在沒關係。它是固定的。謝謝 – guthik

回答

2

您當前的解決方案是不可能維持的,其邏輯看起來像是已經去過地獄和背部:)

我建議你把它分解成簡單的保障性較小的邏輯部分。因此,不是第一次測試的年份,月份和日期是否大於或等於一,你可以組中的所有有關年,月,日爲自己的邏輯

fun daysInMonth n = 
    List.nth([31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], n-1) 

fun reasonable_date (y, m, d) = 
    (* Check year >= 1 *) 
    y >= 1 andalso 

    (* Check 1 <= month <= 12 *) 
    (m >= 1 andalso m <= 12) andalso 

    (* Check 1 <= day <= n, for n being the number of days in specified month *) 
    (d >= 1 andalso d <= daysInMonth m) 

顯然,這不處理閏年,但如果月份是二月,那麼使用輔助函數也很容易實現。它可以像這樣

fun reasonable_date (y, m, d) = 
    (* Check year >= 1 *) 
    y >= 1 andalso 

    (* Check 1 <= month <= 12 *) 
    (m >= 1 andalso m <= 12) andalso 

    (* Check 1 <= day <= n, for n being the number of days in specified month *) 
    (d >= 1 andalso 
    (* If February, and leap year *) 
    ((m = 2 andalso isLeapYear y andalso d <= 29) 
     (* Any other month or non leap year *) 
     orelse d <= daysInMonth m)) 
1

您重複使用條件,如if #2 x = 1 mod 2。這幾乎肯定不會像你想象的那樣工作。這裏,mod是一個算術運算符,意思是將1除以2得到的餘數,而不是數學表達式#2 x等於1模2。因此,不是測試#2 x是否爲奇數,而是測試它是否等於1。通過你的條件,你真的只允許true#2 x是1,所以你的合理日期必須在1月份(甚至可能沒有,我沒有通過所有條件)。

+0

謝謝,這很有用。 :)它是固定的,現在我要重塑它來處理閏年:) – guthik

-1

做我喜歡這個解決方案,它似乎更具可讀性

fun reasonable_date (y, m, d) = 
    let val daysInMonth = 
      List.nth([31, if isLeapYear y then 29 else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], m-1) 
    in 
     (* Check year >= 1 *) 
     y >= 1 andalso 

     (* Check 1 <= month <= 12 *) 
     (m >= 1 andalso m <= 12) andalso 

     (* Check 1 <= day <= n, for n being the number of days in specified month *) 
     (d >= 1 andalso d <= daysInMonth) 
    end 

,但可能是我錯過了一些技巧(我假設你已經寫了一個輔助函數isLeapYear)