递归时保持变量(递归后返回初值)

问题描述 投票:0回答:2

如何在递归函数中保留变量? 假设我有这个功能,想打印我输入的初始值,如果这样的话,这段代码不能完成这项工作,它只会返回 5。我该如何完成这项工作?我想这与 gensym 有关。

(defun cprog (x) 
  (let ((d x)) 
    (if (< x 5) 
      (cprog (1+ x)) 
      (print d))))

感谢您的宝贵时间!

variables recursion common-lisp
2个回答
3
投票

递归调用后,返回当前参数。

(defun cprog (x) 
  (if (< x 5) 
    (cprog (1+ x))
    (print x))
  x)

(cprog 1)
将在递归结束时打印
5
并返回
1
.


2
投票

Barmar 的回答 对于您的简单情况是可以的,但请注意这种实现的后果:它不能进行尾递归,因为每次调用

cprog
都必须存储在程序调用堆栈中,因为在每次
cprog
调用之后,
x
必须退货。 没有尾递归对于你的简单案例来说不是问题,但在生产环境中你宁愿那样实现它:

(defun cprog (x &optional (res x))
  (if (< x 5)
      (cprog (1+ x) res)
      (and (print x) res)))

在这个实现中,你使用尾递归,即:你的普通lisp编译器将你的递归转换为一个简单的循环(可以通过查阅那些函数的dissambly看到),因此你的程序调用堆栈不会被太多耗尽递归引起的函数调用。

在生产系统中,这很重要,因为您可能有很多递归,如果您不使用尾递归,则可能会出现“程序堆栈溢出”。

© www.soinside.com 2019 - 2024. All rights reserved.