我正在嘗試在 LISP 中混洗一個稱為模式的 (81 2 2) 陣列。我在下面使用了這個代碼,但是當我列印模式時,原始陣列被回傳(它沒有被洗牌)。我對這個函式的呼叫是:(shuffle(list patterns))
(setq patterns (make-array '(81 2 2)
:initial-contents
'(((1.0 1.0) (0.0 0.0))
((1.0 2.0) (0.0 1.0))
((1.0 3.0) (0.0 1.0))
((1.0 4.0) (0.0 1.0))...
(defun shuffle (patterns)
(loop for i from (length patterns) downto 2
do(rotatef (elt patterns ( 1(random 80)))
(elt patterns (i))))
patterns)
uj5u.com熱心網友回復:
; compilation unit finished
; Undefined function:
; I
; caught 1 STYLE-WARNING condition
要呼叫函式(I)在(elt patterns (i))。如果要訪問iin位置的元素,則需要洗掉括號patterns。您在運行時沒有錯誤,因為您從不執行此運算式。
(shuffle (list patterns))
您提供的引數shuffle是一個元素串列,即陣列。
由于串列的長度為 1,loop所以什么都不做:
(loop for i from (length (list :something)) downto 2 collect i)
=> NIL
最后,elt用于訪問序列,串列或向量(單維陣列)。目前尚不清楚您要實作的目標,但您應該訪問元素,(aref patterns ...)其中 where...代表與維度一樣多的引數(此處為 3)。
uj5u.com熱心網友回復:
正如coredump 指出的那樣,您只是在改組將陣列包裝在其中的串列,這沒有多大意義。
似乎您不想洗牌整個陣列,而是保持行完好無損,只對行進行洗牌。為此,您仍然需要完全參考每個單元格,因為 Common Lisp 中的多維陣列不是嵌套向量。
您需要行數,即(array-dimension array 0). 陣列索引從 0 到比大小小 1,因此您的 Fisher-Yates 回圈應該從那里開始(您在那里有一個偏離一的錯誤)。您需要向下查找第二個元素,它的索引為 1(再次關閉)。您需要確定尚未隨機確定的元素的隨機元素,因此您的隨機范圍應該只包括當前索引(常量 80 是錯誤的)。在每一行,您需要回圈并復制該行中的單元格。您可以通過在其余維度上嵌套回圈來做到這一點,也可以通過自己計算索引(可能array-row-major-index對此有所幫助)并使用row-major-aref.
相反,如果您真的想在不保留行的情況下對整個陣列進行混洗,則可以使用array-total-sizeand進行正常的 Fisher-Yates 混洗row-major-aref。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/341263.html
下一篇:如何每秒更新一個字串串列?
