【发布时间】:2012-06-15 18:33:10
【问题描述】:
我在 LISP 中有一个递归函数可以将列表向右或向左旋转,如下所示:
(如果是正数-往左推,如果是负数-往右推)
> (rotate-n ‘(5 6 7 8 9) -3)
(7 8 9 5 6)
> (rotate-n ‘(5 6 7 8 9) 3)
(8 9 5 6 7)
功能:
(defun rotate-n (L n)
(cond ((= n 0) L)
((> n 0) (rotate-n (rotate-left L) (- n 1)))
((< n 0) (rotate-n (rotate-right L) (+ n 1)))))
有没有办法使用尾递归获得相同的结果? rotate-right 和 rotate-left 功能正常。
编辑: 我很困惑。我上面写的函数是尾递归。如果我没记错的话,这个函数就是为了相同目的的常规递归:
(defun rotate-n-r (L n)
(cond ((= n 0) L)
((> n 0) (rotate-left (rotate-n-r L (- n 1))))
((< n 0) (rotate-right (rotate-n-r L (+ n 1))))))
【问题讨论】:
-
您的左旋转和右旋转功能可用吗?因为它们必须被修改/包含在 rotate-n 中才能使尾递归起作用。
-
当然,我写了它们并且它们有效。你认为有可能用尾递归解决它吗?
-
是的,但我不确定这是一个好主意:无论哪种方式,效果都完全相同。这种方法几乎是尾递归:在进行递归调用之前旋转。
-
为什么你认为当前的实现不是尾递归的? cond 的最后一次调用是
rotate-n -
@paul 在这里拥有它的权利。除非你的意思是你希望你的 rotate-left 和 -right 函数是尾递归的,这可能是也可能不是。
标签: recursion functional-programming lisp rotation tail-recursion