2012-06-26 82 views
1

我想編寫一個輸出列表的函數。 函數獲取一個列表並輸出一個新列表。例如:在Lisp中用defun重寫列表

(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) 

SO 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: 警告:引用未定義功能:同時

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))) 

這是一個更大的任務的一部分,我們也沒有在口齒不清得到多少教育,更像是:這樣做在口齒不清。

+0

我認爲lisp的全部意義在於,你可以做很多事情,而且必須具有賦值(set,setq等)。作業使事情變得更加困難,所以只能在有好處的地方使用它。你不需要分配這個問題。不使用任務重寫。 –

+1

這功課呢? –

+2

Lisp是哪個? –

回答

1

您可以簡化您的答案是:

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

假設這是Common Lisp的,然後我會列出在你的代碼的一些問題:

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

SETQ不聲明變量,它只是設置它們。

(setq i 0) 
    (while (<= i (length list)) 

WHILE在Common Lisp中不存在。

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

0不是一個列表。因此你不能連接它。 CONCATENATE沒有副作用。你在這裏做什麼都失去了。 NEWLIST這裏是一個符號,而不是一個列表。不起作用。

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

i在這裏不是一個變量。把它列入清單將沒有。 CONCATENATE沒有副作用。你在這裏做什麼都失去了。 NEWLIST這裏是一個符號,而不是一個列表。不起作用。

(+ i 1) 

上述效果丟失。

(remove 0 newlist) 

上述效果丟失。

)) 
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))) 

但可用於學習的目的是有用的/誰知道你的教授期望什麼。