这是一个非常简单的程序,它只是将输入作为一个洗牌的列表返回。我在python中编写了这个程序。现在我想将此程序转换为lisp代码。但我不能。如何在lisp中写下这个程序?
def my_shuffle(a, b, c, d):
return [b, c, d, a]
我尝试了以下代码,但发生了错误。
(defun my_shuffle (a b c d) (list b c d a))
答案 0 :(得分:5)
这里有几件我认为需要指出的事情。首先,您提供的代码是正确的,但是会对列表进行随机播放,提供您传递的四个算法的新列表,总是使用相同的顺序。首先洗牌的是:
生成有限序列的随机排列
从维基百科你可以找到几种算法:
https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
同样在rosseta code中有一个knuth shuffle的实现:
(defun nshuffle (sequence)
(loop for i from (length sequence) downto 2
do (rotatef (elt sequence (random i))
(elt sequence (1- i))))
sequence)
然后,如果你在repl中应用它:
CL-USER> (nshuffle (list 1 2 3 4))
(3 1 4 2)
CL-USER> (nshuffle (list 1 2 3 4))
(3 1 2 4)
注意同一个列表中有两个不同的结果! (同样可以发生,因为是随机顺序)
在python中有构建算法:
https://docs.python.org/3/library/random.html#random.shuffle
也在Common lisp库Alexandria中:
CL-USER> (ql:quickload :alexandria)
To load "alexandria":
Load 1 ASDF system:
alexandria
; Loading "alexandria"
(:ALEXANDRIA)
CL-USER> (alexandria:shuffle (list 1 2 3 4))
(3 2 4 1)
答案 1 :(得分:2)
(defun my_shuffle (a b c d) (list b c d a))
上面的代码定义了一个函数,它将采用 4项并返回这4项的重新排列列表。它可以输入4个列表,4个原子,4个数字,4个任何东西,但它不能分离单个列表中的子列表。
你能做的是:
(defun my_shuffle (myList)
(list (second myList) (third myList) (fourth myList) (first myList)))
或
(defun my_shuffle (myList)
(list (cadr myList) (caddr myList) (cadddr myList) (car myList)))
或
(defun my_shuffle (myList)
(list (nth 1 myList) (nth 2 myList) (nth 3 myList) (nth 1 myList)))
<小时/>
car
返回列表的第一个元素
cdr
返回列表的尾部(列表的car
后面的列表的一部分)
我已经使用car和cdr的组合来提取列表的不同元素。在教科书中找到它。
first
,second
,third
,fourth
相对容易使用,与car
,cadr
,{做同样的事情{1}}和caddr
cadddr
返回列表中的第(x + 1)项,从零开始计数。
所以,
(第3个(列出a b c d))=&gt; d
(第n 0(列出a b c d))=&gt;一个
等等。