如何使用Lisp中的迭代函数打印列表中奇数位置的元素?

如何使用Lisp中的迭代函数打印列表中奇数位置的元素?,lisp,common-lisp,Lisp,Common Lisp,我必须在lisp中创建一个递归函数,它获取一个列表,并生成另一个列表,其中只包含给定列表中奇数位置的元素 如果我有(12345)我必须输出(1355) 我这里有一个代码: (defun pozpar(lst) (do( (l lst (cddr l)) (x '() (cons x (car l)))) ((null l) x))) 这将产生: (5 3 1) 我知道cons在开始时添加了元素,我尝试了append或list,但没有任何效果。最简单的方法是: (defun pozpar (

我必须在lisp中创建一个递归函数,它获取一个列表,并生成另一个列表,其中只包含给定列表中奇数位置的元素

如果我有
(12345)
我必须输出
(1355)

我这里有一个代码:

(defun pozpar(lst) (do(
(l lst (cddr l)) 
(x '() (cons x (car l))))
((null l) x)))
这将产生:

(5 3 1)
我知道
cons
在开始时添加了元素,我尝试了
append
list
,但没有任何效果。

最简单的方法是:

(defun pozpar (lst)
  (do ((l lst (cddr l))
       (x '() (cons (car l) x)))
      ((null l)
       (nreverse x))))

(pozpar '(1 2 3 4 5))
==> (1 3 5)
注释

  • 这将返回而不是输出所需的值

  • 预设值并还原结果是常见的Lisp编码模式

  • 因为它的参数长度是线性的,所以在循环中使用它会产生二次代码

  • 我在文件中格式化了代码。如果您使用这种风格,lispers将更容易阅读您的代码,从而更愿意帮助您

  • 最简单的方法是获得以下结果:

    (defun pozpar (lst)
      (do ((l lst (cddr l))
           (x '() (cons (car l) x)))
          ((null l)
           (nreverse x))))
    
    (pozpar '(1 2 3 4 5))
    ==> (1 3 5)
    
    注释

  • 这将返回而不是输出所需的值

  • 预设值并还原结果是常见的Lisp编码模式

  • 因为它的参数长度是线性的,所以在循环中使用它会产生二次代码

  • 我在文件中格式化了代码。如果您使用这种风格,lispers将更容易阅读您的代码,从而更愿意帮助您


  • 使用
    loop
    可以很容易地按处理顺序获取元素。它也是最有效的,也是唯一保证能处理所有长度参数的方法:

    (defun pozpar1 (lst)
      (loop :for e :in lst :by #'cddr 
            :collect e)))
    
    如果你真的想要递归,我会用一个累加器来完成它,最后用一个线性更新的反向:

    (defun pozpar2 (lst)
      (labels ((helper (lst acc)
                 (if (endp lst)
                     (nreverse acc)
                     (helper (cddr lst) (cons (car lst) acc)))))
        (helper lst '())))
    
    但是,经典的非尾部递归版本如下所示:

    (defun pozpar3 (lst)
      (if (endp lst)
          '()
          (cons (car lst) (pozpar3 (cddr lst)))))
    

    使用
    loop
    可以很容易地按处理顺序获取元素。它也是最有效的,也是唯一保证能处理所有长度参数的方法:

    (defun pozpar1 (lst)
      (loop :for e :in lst :by #'cddr 
            :collect e)))
    
    如果你真的想要递归,我会用一个累加器来完成它,最后用一个线性更新的反向:

    (defun pozpar2 (lst)
      (labels ((helper (lst acc)
                 (if (endp lst)
                     (nreverse acc)
                     (helper (cddr lst) (cons (car lst) acc)))))
        (helper lst '())))
    
    但是,经典的非尾部递归版本如下所示:

    (defun pozpar3 (lst)
      (if (endp lst)
          '()
          (cons (car lst) (pozpar3 (cddr lst)))))
    

    我认为这是一个更简单的解决方案:

    (defun popzar (lst)
      (cond
      ((null lst) nil)
      ( t (cons  (car lst) (popzar (cdr (cdr lst)))))
    ))
    

    它首先检查列表是否为空,如果不是空,则使用第一个元素创建一个新列表,并使用列表中除第二个元素以外的其余元素再次调用自己的结果。

    我认为这是一种更简单的解决方案:

    (defun popzar (lst)
      (cond
      ((null lst) nil)
      ( t (cons  (car lst) (popzar (cdr (cdr lst)))))
    ))
    

    它首先检查列表是否为空,如果不是空,则使用第一个元素创建一个新列表,并使用列表中除第二个元素以外的其余元素再次调用自己的结果。

    有很多Lisp。看起来您在这里使用的是Common Lisp,因此我建议为您正在使用的特定Lisp添加一个标记。这看起来不像是递归函数。没有使用递归。有很多Lisp。看起来您在这里使用的是Common Lisp,因此我建议为您正在使用的特定Lisp添加一个标记。这看起来不像是递归函数。没有使用递归。