0

渡された引数が妥当な日付である場合はtrueを返し、そうでない場合はfalseを返すことになっている次の関数があります。問題は、明らかに妥当な日付でも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
4

3 に答える 3

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))
于 2013-01-23T18:33:43.363 に答える
1

のような条件を繰り返し使用しますif #2 x = 1 mod 2。これは、あなたが思っているように、ほぼ確実に機能しません。ここで、modは算術演算子です。これは、1を2で割ったときに得られる余りを意味し、2を法として1に等しいという数式ではありません#2 x。したがって、奇数かどうかをテストする代わりに、1#2 xに等しいかどうかをテストします。条件では、実際にはが1のtrue場合にのみ許可される#2 xため、妥当な日付はすべて1月でなければなりません(まったくない場合もありますが、すべての条件を処理したわけではありません)。

于 2013-01-23T16:22:13.763 に答える
-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を書いたと思います)

于 2013-01-24T08:26:31.723 に答える