2017-02-15 15 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))