递归函数,它接受一个整数并创建一个二进制列表。
我不明白为什么,if(binList 5)将输出(1 0 1)哪个是正确的,并且(binList 10)的代码导致(追加(binlist 5)'(0 ))不给我(1 0 1 0),但给我(1 1 0 0)。我甚至在Java中写了相同的想法,并且它成功了。递归在Lisp中的工作方式不同吗?还是有什么我想念的?
(defun binList(N)
(cond
((< N 1) '())
((= N 1) '(1))
((> N 1) (if(=(mod N 2) 0)
(append (binList(/ N 2)) '(0))
(append (binList(floor(/ N 2))) '(1))))))
答案 0 :(得分:0)
您的代码实际上会产生正确的结果:
CL-USER> (binlist 10)
(1 0 1 0)
只有几条评论:
binList
只是BINLIST
,这里也不错,但bin-list
会更好。(> n 1)
是多余的。考虑到这些注释,代码将会显示:
(defun bin-list(n)
(cond ((< n 1) '())
((= n 1) '(1))
((zerop (mod n 2)) (append (bin-list (/ n 2)) '(0)))
(t (append (bin-list (floor (/ n 2))) '(1)))))
如果递归代码给出意想不到的结果,首先要做的就是跟踪它:
CL-USER> (trace bin-list)
(BIN-LIST)
CL-USER> (bin-list 10)
0: (BIN-LIST 10)
1: (BIN-LIST 5)
2: (BIN-LIST 2)
3: (BIN-LIST 1)
3: BIN-LIST returned (1)
2: BIN-LIST returned (1 0)
1: BIN-LIST returned (1 0 1)
0: BIN-LIST returned (1 0 1 0)
(1 0 1 0)
正如您所指出的,(bin-list 10)
会产生(append (bin-list 5) '(0))
。在这里,您可以看到原始呼叫(呼叫0)(bin-list 10)
会呼叫(bin-list 5)
(呼叫1)。呼叫1返回(1 0 1)
。最后,调用0将0
添加到结尾。
如果这不起作用,那么你可以调用一个调试器:参见this blog获取Common Lisp调试器的教程(使用SLIME)。