Algorithm 创建快速指数函数

Algorithm 创建快速指数函数,algorithm,ocaml,divide-and-conquer,exponent,Algorithm,Ocaml,Divide And Conquer,Exponent,我很难在OCaml中找到一个更快的典型指数函数。以下是我试图遵循的一些准则: 与典型的递归指数版本的expt b n==>b*(b*(b…)不同,该函数接收两个参数b和n,基本上采取分而治之的姿态 如果n是偶数,则fastexpt bn=>(b^(n/2))^2否则如果n是奇数,则fastexpt bn=>b*(b^(n-1)) 以下是我到目前为止编写的代码: let fastexpt : int -> int -> int = fun b n -> if n = 0

我很难在OCaml中找到一个更快的典型指数函数。以下是我试图遵循的一些准则:

  • 与典型的递归指数版本的
    expt b n==>b*(b*(b…)
    不同,该函数接收两个参数b和n,基本上采取分而治之的姿态
  • 如果n是偶数,则
    fastexpt bn=>(b^(n/2))^2
    否则如果n是奇数,则
    fastexpt bn=>b*(b^(n-1))
  • 以下是我到目前为止编写的代码:

    let fastexpt : int -> int -> int
    = fun b n ->
        if n = 0 then 1
        else if ((n mod 2) = 0) then (expt b (n / 2)) * (expt b (n / 2)) 
        else b * (expt b (n - 1));;
    

    我的问题是:在没有使用<代码> Extp>代码>函数的情况下,有没有办法编写这个函数?

    < p>你在这里做的是第一次使用分而治之的方法,然后用正常的一个来计算剩余部分(如果我们认为你已经声明了代码> EXT )

    另一件事是,如果
    n
    是奇数,则可以返回
    b*b^((n-1)/2)*b^((n-1)/2)
    ,这就是快速求幂的目的

    您应该做的只是将
    fastexpt
    定义为递归,并一直使用它:

    let rec fastexpt : int -> int -> int
    = fun b n ->
        if n = 0 then 1
        else 
          let b2 = fastexpt b (n / 2) in
          if n mod 2 = 0 then b2 * b2 
          else b * b2 * b2;;
    

    改用
    fastexpt
    ?也许我不太了解OCaml语言,但是如果我要包括fastexpt,那么我不需要将fastexpt的初始定义为“let rec”?@Sean,from:发布问题并回复反馈。发布后,将问题在浏览器中打开一段时间,看看是否有人发表评论。如果您遗漏了一条明显的信息,请随时准备通过编辑问题来回复。如果有人发布答案,请随时尝试并提供反馈!请在您你问一个问题,接受答案,回答评论或答案。你所有的问题都没有被接受的答案,这很奇怪。不要粗鲁,人们是来帮助你的,不要离开和交流。@Sean你应该检查你以前的问题,并将答案标记为被接受。这向社区的其他人表明这个问题已经“完成”。请在此处查看您的问题列表:感谢链接@glennsl。我实际上是在浏览我的问题,但我还没有意识到我刚才“抛出”了多少问题。我会尽快处理这些问题。:)如果您尝试使用快速指数,您可以尝试避免使用
    mod
    和除法,因为它们是CPU上的慢速指令。相反,您可以使用位移位操作将整数除以2的幂,并使用位操作测试数字的奇偶性:如果第一位设置为零,则数字为偶数。然而,OCaml编译器可能已经进行了这些优化,但值得一试。是的,谢谢你,我实际上是从算法的角度回答的,但你的观点值得注意。;-)@编译器执行这些优化。如果你想要优化,可能会有黑魔法来确保你的整数在计算过程中保持不固定(尽管我不确定手动操作是否可行)。@Patj好的,太好了!谢谢你的精确性。