在Lisp中用defun重写一个列表

时间:2012-06-26 16:04:14

标签: list loops lisp

我想编写一个输出列表的函数。 该函数获取一个列表并输出一个新列表。例如:

(0 0 1 2 2 1) -> (3 4 4 5 5 6)).

它的作用是:初始列表中的索引+ 1是新列表中的值。并且该值在新列表中放置x次,取决于初始列表中的值。

(1 2) -> (1 2 2)
(0 3 0 3) -> (2 2 2 4 4 4)

所以3在第二个位置,值为3,所以2(第二个位置)在新列表中放置3次。

我想出了这个,这不起作用

(defun change-list (list)
  (setq newlist '(1 2 3))
  (setq i 0) 
  (while (<= i (length list)) 
    (if (= (nth i list) 0)
      (concatenate 'list '0 'newlist)
    (concatenate 'list '(i) 'newlist))
    (+ i 1)
    (remove 0 newlist)))

问题主要在于它无法识别新变量。它给了我这些错误: functions.lisp:27:26:   警告:引用了未定义的函数:while

functions.lisp:31:2:   警告:对未声明的变量newlist的免费引用假设特殊。   警告:对未声明的变量的自由引用我认为是特殊的。

有人明白这一点吗?


我们自己能够解决它:

(defun change-list (a) 
  (loop for j from 1 to (length a) by 1 append 
    (loop for i from 1 to (nth (- j 1) a) by 1 
      collect j )))

这是一个更大的任务的一部分,我们没有接受过很多关于lisp的教育,更像是:在lisp中做。

3 个答案:

答案 0 :(得分:2)

我们假设这是Common Lisp,然后我会列出代码中的一些问题:

(defun change-list (list)
  (setq newlist '(1 2 3))

SETQ不会声明变量,只是设置它们。

  (setq i 0) 
  (while (<= i (length list)) 
Common Lisp中不存在

WHILE

    (if (= (nth i list) 0)
      (concatenate 'list '0 'newlist)

0不是列表。因此你不能连接它。 CONCATENATE没有副作用。你在这做什么都失去了。 NEWLIST这里是符号,而不是列表。不起作用。

      (concatenate 'list '(i) 'newlist))

i此处不是变量。将它放入列表将没有。 CONCATENATE没有副作用。你在这做什么都失去了。 NEWLIST这里是符号,而不是列表。不起作用。

    (+ i 1)

上述效果丢失了。

    (remove 0 newlist)

上述效果丢失了。

    ))

答案 1 :(得分:1)

您可以简化对此的回答:

(defun change-list (list) 
  (loop for i in list and j from 1
        append (loop repeat i collect j)))

答案 2 :(得分:0)

基本上,只是做同样事情的另一种方式:

(defun change-list (x)
  (let ((index 0))
    (mapcon
     #'(lambda (y)
         (incf index)
         (let ((z (car y)))
           (unless (zerop z)
             (make-list z :initial-element index)))) x)))

但可能对学习目的有用或谁知道你教授的期望。