2

我们的任务是以这种方式打印出帕斯卡三角形中的值

(pascal 2)
(1 2 1)
(pascal 0)
(1)

我在互联网某处复制了二项式定理的代码,定义如下:

(defun choose(n k)
        (labels ((prod-enum (s e)
            (do ((i s (1+ i)) (r 1 (* i r))) ((> i e) r)))
          (fact (n) (prod-enum 1 n)))
         (/ (prod-enum (- (1+ n) k) n) (fact k))))

现在我正在尝试从我的 pascal 函数中的值创建一个列表:

(defun pascal (start end) 
  (do ((i start (+ i 1)))
       ((> i end) )
       (print (choose end i) ))
)

如果我用 (pascal 0 2) 测试该函数,它会产生 1 2 1 NIL。如何消除 NIL 并创建列表?

4

1 回答 1

5

注意:我明确没有提供 的实现pascal,因为介绍性的“我们的任务是……”表明这是一项家庭作业。

而不是在每次迭代时打印结果(choose end i),只需将产生的值收集(choose end i)到结果列表中,然后在循环结束时返回结果。通过将元素推入其中来以相反的顺序构造一个列表,然后使用nreverse它来反转它以产生最终的返回值,这是一种常见的习惯用法。例如,您可以range通过以下方式实现:

(defun range (start end &optional (delta 1) &aux (results '()))
  (do ((i start (+ i delta)))
      ((>= i end) (nreverse results))
    (push i results)))

或者(写一个不需要在body中写任何代码的/循环总是让人觉得很满足dodo*。 )

(defun range (start end &optional (delta 1))
  (do* ((results '() (list* i results))
        (i start (+ i delta)))
       ((>= i end) (nreverse results))))

以便

(range 0 10 3)
;=> (0 3 6 9)

但是,由于帕斯卡三角形中的行是回文,因此您不需要反转它们。实际上,由于行是回文,您甚至应该能够调整循环以仅生成列表返回的一半,例如,

(revappend results results)

当有偶数个元素时,并且

(revappend results (rest results))

当有奇数时。

于 2013-09-18T03:03:50.297 回答