代码之家  ›  专栏  ›  技术社区  ›  Sean

确定素数的OCaml程序

  •  0
  • Sean  · 技术社区  · 6 年前

    我试图用OCaml语言编写一个程序,但是在使用嵌套函数时遇到了问题。下面是我写的代码:

    let prime : int -> bool
    = fun x ->
      if x > 2 then
        let a = x - 1 in
          let rec checkZero a x =
            if a > 1 then
              match x mod a with
               0 -> false
              |_ -> checkZero (a - 1) x
            else if a = 1 then
              true
      else if x = 2 then
        true
      else
        false
    ;;
    

    为了简单地解释我的代码,我使用了一个嵌套函数 checkZero 决定是否 x a 开始于 x - 1 一直到2点。

    mod 运算为0,则 不是质数,如果结果是其他的,那么我们从中减去1 并表演 检查零

    我得到的特殊错误消息是,我得到了一个双分号所在的语法错误。

    我不太熟悉OCaml的工作原理,但我知道当您希望整个代码成为一个表达式时,会使用双分号。

    任何反馈都将不胜感激。谢谢您!

    1 回复  |  直到 6 年前
        1
  •  1
  •   Pharoah Jardin    6 年前

    为了将来的参考,这里有一个更简单的函数,它的操作方式与您的相同(没有优化,但更短):

    let prime n =
        let rec checkZero x d = match d with
            | 1 -> true    
            | _ -> (x mod d <> 0) && checkZero x (d-1)
        in match n with
        | 0 | 1 -> false
        | _ -> checkZero n (n-1) ;;
    
        2
  •  0
  •   Sean    6 年前

    我发现了那个问题,现在我觉得自己很傻。我希望它能帮助其他与类似问题作斗争的人。

    正如@glennsl在对这个问题的评论中所说,我遗漏了一件事 let ... in 必须后跟调用它的表达式 checkZero 由于缺少调用,函数未按预期执行。

    if ... then ... else ... 语句,有时执行模式匹配更方便。

    以下是我编写的代码(如果代码中有任何错误,请随时告诉我):

    let prime : int -> bool
    = fun x ->
      match x with
         0 -> false
       | 1 -> false
       | _ -> let a = (x - 1) in
                let rec checkZero a x =
                  if (a > 1) then
                    match x mod a with
                       0 -> false
                     | _ -> checkZero (a - 1) x
                  else
                    true
                  in
                  checkZero a x
    ;;
    

    不使用条件语句的等效版本为:

    let prime : int -> bool
    = fun n ->
      match n with
         0 -> false
       | 1 -> false
       | _ -> let a = (n - 1) in
                let rec checkZero a n =
                  match a with
                     1 -> true
                   | _ -> match n mod a with
                             0 -> false
                           | _ -> checkZero (a - 1) n
                  in
                  checkZero a n
    ;;