2013-01-23 54 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)