使用递归在LISP中使用整数到二进制列表

时间:2016-03-16 04:53:02

标签: list recursion binary lisp

递归函数,它接受一个整数并创建一个二进制列表。

我不明白为什么,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))))))

1 个答案:

答案 0 :(得分:0)

您的代码实际上会产生正确的结果:

CL-USER> (binlist 10)
(1 0 1 0)

只有几条评论:

  • 请使用Lisp名称约定:CL不区分大小写,因此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)。