这是一个非常简单的程序,它只将输入作为列表改组返回。我用python编写了这个程序。现在,我想将此程序转换为Lisp代码。但我做不到 如何用Lisp写下该程序?
def my_shuffle(a, b, c, d):
return [b, c, d, a]
Run Code Online (Sandbox Code Playgroud)
我尝试了以下代码,但发生错误。
(defun my_shuffle (a b c d) (list b c d a))
Run Code Online (Sandbox Code Playgroud)
您在这里需要指出几件事。首先,您提供的代码是正确的,但会随机排列一个列表,然后以相同的顺序显示您通过的四个算法的新列表。首先,将一个序列改组为:
生成有限序列的随机排列
在Wikipedia中,您可以找到几种算法:
https://zh.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
同样在rosseta代码中,有一个knuth shuffle的实现:
(defun nshuffle (sequence)
(loop for i from (length sequence) downto 2
do (rotatef (elt sequence (random i))
(elt sequence (1- i))))
sequence)
Run Code Online (Sandbox Code Playgroud)
然后,如果您在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)
Run Code Online (Sandbox Code Playgroud)
注意同一列表上有两个不同的结果!!!(同样是可能发生的,因为是随机顺序)
在python中,有一些构建算法:
https://docs.python.org/3/library/random.html#random.shuffle
也在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)
Run Code Online (Sandbox Code Playgroud)
(defun my_shuffle (a b c d) (list b c d a))
Run Code Online (Sandbox Code Playgroud)
上面的代码定义了一个函数,它将接受4 个项目并返回这 4 个项目的重新排列列表。它可以接受 4 个列表、4 个原子、4 个数字、4 个任何东西的输入,但它不能分隔单个列表中存在的子列表。
你能做的是:
(defun my_shuffle (myList)
(list (second myList) (third myList) (fourth myList) (first myList)))
Run Code Online (Sandbox Code Playgroud)
或者
(defun my_shuffle (myList)
(list (cadr myList) (caddr myList) (cadddr myList) (car myList)))
Run Code Online (Sandbox Code Playgroud)
或者
(defun my_shuffle (myList)
(list (nth 1 myList) (nth 2 myList) (nth 3 myList) (nth 1 myList)))
Run Code Online (Sandbox Code Playgroud)
car返回列表的第一个元素
cdr返回列表的尾部(列表后面的列表的一部分car) 我使用 car 和 cdr 的组合来提取列表的不同元素。在你的教科书中找到它。
first, second, third,fourth相对容易使用并且与car, cadr,caddr和 做同样的事情cadddr
(nth x list)返回列表的第 (x+1) 个项目,从零开始计数。因此,(nth 3 (list abcd)) => d (nth 0 (list abcd)) => a 等等。