一个递归函数,用于返回lisp中的第n个元素

时间:2013-11-16 16:08:04

标签: recursion common-lisp

我想验证这是否是一个递归函数?需要返回第n个元素,我只是想确保我的工作。

(defun nth2(n lst)
       (let((count 1))
           (loop
               (cond((equal count n)(return (car lst))))
               (setq count (+ count 1))
               (setq lst (cdr lst)))))

确定。我刚试过这个想法。它给了我一个错误:不在名为NIL的块中

(defun nth2(n lst)
    (let((count 1))
      (cond((equal count n)(return (car lst)))
          (t(setq count (+ count 1))
          (nth2(count (cdr (lst))))))))

2 个答案:

答案 0 :(得分:1)

以下是递归工作原理的一般概述......每个递归函数必须具有:

  1. 至少一个基本情况:在基本情况下,递归函数直接执行某些操作,而不调用自身。一个好的递归函数具有简单易懂的基本案例。递归函数有基本情况,因为递归必须在某处停止。

  2. 至少一个递归的情况:在递归的情况下,递归函数将一个复杂的问题分解为一个或多个更容易解决的问题,它通过调用自身来实现。用于调用自身的参数最终需要更接近基本情况(例如,使用n-1(cdr my-list)),以便递归停止。

  3. 您的函数没有任何递归情况,因此它不是递归函数。为了使其递归,请考虑:

    1. 我希望我的基本案例是什么?什么是一个容易解决的问题? (提示:替换列表前面的值很容易。)

    2. 我希望我的递归案例是什么?如何让问题看起来更像我的基本情况?

答案 1 :(得分:1)

正如我在此answer中所写,您需要使用递归函数来避免setqsetf等。

您可以倒计时,而不是计算并且不得不使用其他变量。假设索引从0开始,例如:

  (nth2 2 '(a b c d e))
= (nth2 1 '(b c d e))
= (nth2 0 '(c d e))
= (car '(c d e))
= 'c

所以你必须在删除第一个元素时递减到0,然后在索引为0时返回第一个元素:

(defun nth2 (n lst)
  (if (zerop n)
    (car lst)
    (nth2 (1- n) (cdr lst))))