编辑列表中的每个偶数索引元素

时间:2018-03-30 08:36:38

标签: lisp common-lisp

我是lisp的新手,我想创建一个函数,每个偶数索引元素都用一个包含该元素的新元素列表替换它。例如

  

(1 2 3 4 5) - > (1(2)3(4)5),(1 2 3 4 5 6) - > (1(2)3(4)5(6))

现在我想出了解决方案,每个元素都放在它自己的列表中,但我无法准确地选择每个偶数索引元素:

(DEFUN ON3 (lst)
 ((ATOM (CDR lst)) (CONS (CONS (CAR lst) NIL) NIL))
 (CONS (CONS (CAR lst) NIL) (ON3 (CDR lst)))) 

2 个答案:

答案 0 :(得分:2)

您的代码无效。您需要使用ifcond,以便代码遵循其中的一个路径。现在你有一个错误,正在调用一个名为(atom (cdr lst))的函数。如果它是有效的东西,它将是死代码,因为下一行总是运行,无论如何。它是无限递归。

所以怎么算。您可以将每个步骤一次视为2个元素的句柄。您需要注意以下事项:

(enc-odds '())         ; ==> ()
(enc-odds '(1))        ; ==> (1)
(enc-odds '(1 2 3 ...) ; ==> (1 (2) (enc-odds (3 ...))

另一种方法是使用额外的参数创建一个帮助器:

(defun index-elements (lst)
  (labels ((helper (lst n)
             (if (null lst)
                 lst
                 (cons (list (car lst) n)
                       (helper (cdr lst) (1+ n))))))
    (helper lst 0)))
(index-elements '(a b c d))
; ==> ((a 0) (b 1) (c 2) (d 3))

答案 1 :(得分:2)

对于非递归解决方案,循环允许构造同步迭代器:

(defun every-second (list)
  (loop
      for a in list
      for i upfrom 1
      if (evenp i) collect (list a)
      else collect a))

(every-second '(a b c d e))
; ==> (A (B) C (D) E) 

有关循环的详细解释,请参阅http://www.gigamonkeys.com/book/loop-for-black-belts.html