【问题标题】:Binomial Coefficient using Tail Recursion in LISP在 LISP 中使用尾递归的二项式系数
【发布时间】:2011-05-03 01:34:23
【问题描述】:

我想编写一个函数来使用尾递归查找 C(n,k),非常感谢您的帮助。

我已经达到了:

(defun tail-recursive-binomial (n k)
  (cond ((or (< n k) (< k 0)) NIL)
        ((or (= k 0) (= n k)) 1)
        (T (* (tail-recursive-binomial (- n 1) (- k 1)) (/ n k)))))

使用the following property of the binomial coefficients

但我不知道如何使递归调用成为每个实例执行的最后一条指令,因为最后一条是产品。我一直在尝试使用辅助功能,我认为这是唯一的方法,但我还没有找到解决方案。

【问题讨论】:

    标签: recursion lisp tail-recursion binomial-coefficients


    【解决方案1】:

    正如 starblue 建议的那样,使用递归辅助函数:

    (defun binom (n k)
      (if (or (< n k) (< k 0))
        NIL  ; there are better ways to handle errors in Lisp
        (binom-r n k 1)))
    
    ;; acc is an accumulator variable
    (defun binom-r (n k acc)
      (if (or (= k 0) (= n k))
        acc
        (binom-r (- n 1) (- k 1) (* acc (/ n k)))))
    

    或者,给主函数一个 optional 累加器参数,默认值为 1(递归基本情况):

    (defun binom (n k &optional (acc 1))
      (cond ((or (< n k) (< k 0)) NIL)
            ((or (= k 0) (= n k)) acc)
            (T (binom (- n 1) (- k 1) (* acc (/ n k))))))
    

    后一个选项的效率略低,因为每次递归调用都会检查错误情况。

    【讨论】:

    • 非常感谢。我一直在寻找像第一个这样的解决方案(更类似于我制作或看到的其他功能),但我喜欢第二个,非常优雅。
    【解决方案2】:

    您需要一个带有额外参数的辅助函数,用于计算和传递结果。

    【讨论】:

    • 那是我最初的方法,因为我用这种方式编写了阶乘函数,但我没有得到它。还是谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 2012-06-15
    • 2021-10-10
    相关资源
    最近更新 更多