我有以下函数,如果传递的参数是合理的日期则返回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 :(得分:2)
您当前的解决方案无法维护,其逻辑看起来像是地狱般的东西:)
我建议您将其分解为更小的逻辑部分,以确保简单的属性。因此,不是首先测试年,月和日是否大于或等于1,您可以将所有关于年,月和日的逻辑分组给自己
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)
显然这不会处理闰年,但是如果月份是2月,使用辅助函数实现也很简单。它可以这样做
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 :(得分:1)
您反复使用if #2 x = 1 mod 2
等条件。这几乎肯定不会像你想象的那样奏效。这里,mod
是算术运算符,表示将1除以2时得到的余数,而不是表示#2 x
等于1模2的数学表达式。因此,不是测试是否#2 x
很奇怪,你正在测试它是否等于1.按照你的条件,当true
为1时你真的只允许#2 x
,所以你的合理日期必须全部在1月(甚至可能没有是任何,我没有完成所有条件)。
答案 2 :(得分:-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)