2017-02-15 44 views
1

转移列表清单很容易,但有一个警告,即不得超过call-arguments-limit在lisp中转换列表清单的安全方法?

http://www.lispworks.com/kb/4fbc798cb17237ca852566da005fcc79.html

什么是转写为当列表的长度可能会超出call-arguments-limit一种安全的方式?

例如,答案是没有这一项:https://stackoverflow.com/a/3513158/914859

(defun transpose (list-of-lists) 
    (apply #'mapcar #'list list-of-lists)) 
+0

http://stackoverflow.com/questions/39943232/matrix-transpose-common-lisp关于什么 – anquegi

回答

5

这里是一个非递归版本支配 通过call-arguments-limit等:

(defun pop-all (list-of-lists) 
    "Pop each list in the list, return list of pop results 
and an indicator if some list has been exhausted." 
    (loop for tail on list-of-lists collect (pop (car tail)))) 

(defun transpose (list-of-lists) 
    "Transpose the matrix." 
    (loop with tails = (copy-list list-of-lists) 
    while (some #'consp tails) ; or any? 
    collect (pop-all tails))) 

测试:

(defparameter ll '((1 4 7) (2 5 8) (3 6 9))) 
(transpose ll) 
==> ((1 2 3) (4 5 6) (7 8 9)) 
ll 
==> ((1 4 7) (2 5 8) (3 6 9)) 
(equal ll (transpose (transpose ll))) 
==> T 

请注意,我扫描list-of-lists两次每次迭代 - 一次在some和一次在pop-all(与similar answer相同)。

我们可以用一些额外的工作避免:

(defun pop-all (list-of-lists) 
    "Pop each list in the list, return list of pop results 
and an indicator if some list has been exhausted." 
    (loop for tail on list-of-lists 
    for more = (consp (car tail)) then (and more (consp (car tail))) 
    collect (pop (car tail)) into card 
    finally (return (values cars more)))) 

(defun transpose (list-of-lists) 
    "Transpose the matrix." 
    (loop with tails = (copy-list list-of-lists) and more and cars 
    do (setf (values cars more) (pop-all tails)) 
    while more collect cars))