2012-09-30 58 views
2

這是我在普通lisp中的第一個作業的一部分。Lisp:生成一個10個隨機整數的列表

我們必須定義一個變量來表示0到100之間的任意10個隨機整數: 我不確定這裏提出的是什麼。 我應該寫:(setf var1 '())

然後,我們必須定義一個函數,它可以生成10個隨機整數的列表並返回一個包含這些數字的列表。

這是我寫的,但我一直得到NIL作爲我的輸出。你知道什麼是錯的代碼:

(setf *random-state* (make-random-state t)) 
(setf var1 '()) 


(defun randlist (var1) 
(dotimes (i 10) 
    (setf temp (random 101)) 
     (cons 'temp var1 ))) 
+0

您正在使用名爲'var1'的函數參數隱藏全局變量'var1'。另外,不需要使用全局變量,只需使函數返回一個新列表並將結果賦給變量。全局變量是邪惡的。 –

回答

5

編寫一個函數,返回一個新的列表與10個隨機整數:

(defun randlist() 
    (let ((lst())) 
    (dotimes (i 10) 
     (setf lst (cons (random 101) lst))) 
    lst)) 

然後你就可以將其結果賦值給變量:

(defvar var1 (randlist)) 

DEMO

+0

謝謝!我開始學習lisp :) – user1561949

+0

'(setf var1(randlist))'和'(defparameter var1(randlist))''有什麼區別? – user1561949

+0

'setf'可以被看作是一個更一般的*賦值操作符。它通常用於*改變先前聲明的變量的值。 'defvar'與'defparameter'非常相似,但它只允許你定義一次變量值。查看我創建的這個演示http://ideone.com/5b8iw的最後部分,以查看其差異。 –

6

你不需要像那樣初始化*random-state*。無論如何,這是默認設置。如果你有一個不同的隨機數發生器的實現,你需要初始化它。

雖然(setf whatever nil)可能會工作,但這不是您聲明變量的方式。 setf是一個用於爲符號賦值的宏。通常情況下,您首先創建符號然後分配給它們。如果你需要一個動態的變量,你的選擇是defparamterdefvar宏,例如:

(defparameter var1 nil) 
(defvar var2 nil) 

你的函數返回randlistnil這是dotimes宏觀回報,這是在函數中執行的最後形式。您可以將其更改爲返回var1,但使用動態變量,特別是以這種方式不是一種好的編碼習慣。它聽起來像是被要求寫一個返回十個整數列表的函數,而不需要將它分配給函數外部的一個動態變量。

(defun randlist() 
    (loop for i from 0 below 10 collect (random 101))) 

這可能是最簡單的方法。但有很多很多其他的方法:)

只是爲了好玩,這裏有一個替代方案,但它不是特別好。我希望它是更短,但它是不是真的:)

(defun random-list() 
    (mapcar #'random (make-list 10 :initial-element 101))) 
+0

謝謝你讓我看到不同的選擇。這對我來說是學習語言的好方法:) – user1561949

0

或者你可以做這樣的 -

(defun rnd-list() 
    (let (lst) 
    (dotimes (n 100) 
     (push (random 101) lst)) 
    (reverse lst))) 
1

允許遞歸做到這一點:

(defun rnd-list() 
    (rnd-list-1 10 10)) 

(defun rnd-list-1 (limit count) 
    (cond ((<= count 0) 
     nil) 
     (t 
     (cons (random limit) 
       (rnd-list-1 limit (1- count)))))) 
+0

當你爲了完成任務而被迫忽略迭代的時候非常有用; MEH – MarZab