在 Lisp 的列中打印嵌套列表

print nested lists in columns in Lisp

我对如何连续打印多个类似矩阵的嵌套列表有疑问,一行又一行,垂直对齐,以便它们出现在另一列下的列中。

我尝试了几种方法,但 none 行得通,而且我使用了多种文本格式,但效果不如预期。有什么建议吗?

我更新了疑惑,希望现在你能看懂

(defun tabA()
  '((X 0 0 0 0 0 0) 
    (0 0 0 X 0 0 0) 
    (0 0 0 0 0 0 0) 
    (0 0 0 T 0 0 0)  
    (0 0 0 0 0 0 0)))

(defun tabB()
  '((0 0 0 0 X 0 0) 
    (0 0 0 0 0 0 0) 
    (0 T 0 0 0 0 0) 
    (0 0 0 X 0 0 0)  
    (0 0 0 0 0 0 0)))

(defun tabC()
  '((0 0 0 T 0 0 0) 
    (0 0 0 0 0 0 0) 
    (0 0 X 0 0 X 0) 
    (0 0 0 0 0 0 0)  
    (0 0 0 0 0 0 0)))

(defun states ()
  (list (tabA) (tabB) (tabC)))

(defun test-print ()
  (format T "~%--- Result ---")
  (mapcar #'(lambda(x) (print-state x)) (states)))

(defun print-state (x)
  (format T "~%")
  (mapcar (lambda (x) (format T "~@T~@T~@T~@T~@T ~A ~%" x)) x)
  (format NIL ""))

  ;;test print
  (test-print)

你可以在 ideone.com 中测试并查看结果,就像这个例子

--- Result ---
  (X 0 0 0 0 0 0) 
  (0 0 0 X 0 0 0) 
  (0 0 0 0 0 0 0) 
  (0 0 0 T 0 0 0) 
  (0 0 0 0 0 0 0) 

  (0 0 0 0 X 0 0) 
  (0 0 0 0 0 0 0) 
  (0 T 0 0 0 0 0) 
  (0 0 0 X 0 0 0) 
  (0 0 0 0 0 0 0) 

  (0 0 0 T 0 0 0) 
  (0 0 0 0 0 0 0) 
  (0 0 X 0 0 X 0) 
  (0 0 0 0 0 0 0) 
  (0 0 0 0 0 0 0) 

我想将这些列表打印成两列或三列,就像这个例子

--- Result ---
(X 0 0 0 0 0 0)  (0 0 0 0 X 0 0) 
(0 0 0 X 0 0 0)  (0 0 0 0 0 0 0) 
(0 0 0 0 0 0 0)  (0 T 0 0 0 0 0) 
(0 0 0 T 0 0 0)  (0 0 0 X 0 0 0) 
(0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)

(0 0 0 T 0 0 0) 
(0 0 0 0 0 0 0) 
(0 0 X 0 0 X 0) 
(0 0 0 0 0 0 0) 
(0 0 0 0 0 0 0)

如果输入像示例数据一样是规则的,这可以通过遍历 tables 的行索引并遍历 tables 本身来打印行来完成按顺序:

(defun print-tables (tables)
  (let ((rows (length (first tables))))
    (loop for n below rows do
         (terpri)
         (dolist (table tables)
           (format t "~A  " (elt table n))))))

print-tables 函数将 table 的列表作为其参数。这里假设 table 都是相同的形状,具有规则的列宽。 rows 的数量是为第一个 table 计算的,而 loop 计算从 0 开始的行索引,在 [=44= 的每个序列之前用 (terpri) 打印一个换行符] 行被打印出来。 dolist 迭代 tables 并且对于每个 table 打印第 n 行。同样的方法可以用于更不规则的数据,加上一些额外的格式化代码。

SCRATCH> (print-tables (list (tabA) (tabB) (tabC)))

(X 0 0 0 0 0 0)  (0 0 0 0 X 0 0)  (0 0 0 T 0 0 0)  
(0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  
(0 0 0 0 0 0 0)  (0 T 0 0 0 0 0)  (0 0 X 0 0 X 0)  
(0 0 0 T 0 0 0)  (0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  
(0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  
NIL

上面的代码只是在一行 table 中按顺序打印 tables,但是对于更多的 tables 来说,将 tables 分组会很好=44=]s 很明智。 group-tables 函数可以编写并在 print-groups 函数中使用上述 print-tables 函数。

(defun group-tables (grouping tables)
  (labels ((iter (tables group)
             (cond ((null tables)
                    (list group))
                   ((= (length group) grouping)
                    (cons group
                          (iter tables '())))
                   (t
                    (iter (rest tables)
                          (append group (list (first tables))))))))
    (iter tables '())))

此处 group-tables 采用 table 的列表和一个整数参数,指定每个输出行所需的最大分组。本地 iter 函数构建了一个组列表,但每个组都是在累加器中构建的;请注意,这里使用 append 来保持 table 与输入的顺序相同。

(defun print-groups (grouping tables)
  (dolist (group (group-tables grouping tables))
    (print-tables group)
    (terpri)))

这里print-groups只是用group-tables把table分到组里,然后用dolist挑出每个单独的组给[=15处理=]函数。

示例 REPL 交互:

SCRATCH> (print-groups 3 (list (tabA) (tabB) (tabC)))

(X 0 0 0 0 0 0)  (0 0 0 0 X 0 0)  (0 0 0 T 0 0 0)  
(0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  
(0 0 0 0 0 0 0)  (0 T 0 0 0 0 0)  (0 0 X 0 0 X 0)  
(0 0 0 T 0 0 0)  (0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  
(0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  
NIL
SCRATCH> (print-groups 2 (list (tabA) (tabB) (tabC)))

(X 0 0 0 0 0 0)  (0 0 0 0 X 0 0)  
(0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  
(0 0 0 0 0 0 0)  (0 T 0 0 0 0 0)  
(0 0 0 T 0 0 0)  (0 0 0 X 0 0 0)  
(0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  

(0 0 0 T 0 0 0)  
(0 0 0 0 0 0 0)  
(0 0 X 0 0 X 0)  
(0 0 0 0 0 0 0)  
(0 0 0 0 0 0 0)  
NIL
SCRATCH> (print-groups 3 (list (tabA) (tabB) (tabC) (tabA) (tabB) (tabC)))

(X 0 0 0 0 0 0)  (0 0 0 0 X 0 0)  (0 0 0 T 0 0 0)  
(0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  
(0 0 0 0 0 0 0)  (0 T 0 0 0 0 0)  (0 0 X 0 0 X 0)  
(0 0 0 T 0 0 0)  (0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  
(0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  

(X 0 0 0 0 0 0)  (0 0 0 0 X 0 0)  (0 0 0 T 0 0 0)  
(0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  
(0 0 0 0 0 0 0)  (0 T 0 0 0 0 0)  (0 0 X 0 0 X 0)  
(0 0 0 T 0 0 0)  (0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  
(0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  
NIL
SCRATCH> (print-groups 4 (list (tabA) (tabB) (tabC) (tabA) (tabB) (tabC)))

(X 0 0 0 0 0 0)  (0 0 0 0 X 0 0)  (0 0 0 T 0 0 0)  (X 0 0 0 0 0 0)  
(0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 X 0 0 0)  
(0 0 0 0 0 0 0)  (0 T 0 0 0 0 0)  (0 0 X 0 0 X 0)  (0 0 0 0 0 0 0)  
(0 0 0 T 0 0 0)  (0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 T 0 0 0)  
(0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  

(0 0 0 0 X 0 0)  (0 0 0 T 0 0 0)  
(0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  
(0 T 0 0 0 0 0)  (0 0 X 0 0 X 0)  
(0 0 0 X 0 0 0)  (0 0 0 0 0 0 0)  
(0 0 0 0 0 0 0)  (0 0 0 0 0 0 0)  
NIL