如何在 Lisp 的子列表中排序列表?

How to order a list in sublists in Lisp?

我有一个这样的列表:

(4 5 6 3 12 22 4 4 55 43 1 4 0) 

并想要这样的输出:

((4 5 6) (3) (12 22) (4) (4 55) (43) (1 4) (0)) 

我想你可以猜出顺序,它是升序的,我是 Lisp 的新手,需要一些帮助

这是 TXR Lisp 中的一种可能解决方案:

(defun ascending-partitions (list)
  (let ((indices (mappend (do if (>= @1 @2) (list @3))
                          list (cdr list) (range 1))))
    (split list indices)))

我们获取列表中不大于其前身的元素的数字索引位置;然后我们使用 split 函数在这些索引处将列表切成碎片。

通过 mappend 函数处理三个列表来计算索引:原始 list,与删除第一个元素的同一个列表并行 (cdr list),以及一个(range 1).

生成的从 1 开始的无限递增整数列表

do宏为我们写了一个匿名函数,其中表达式中嵌入的@1@2@3变量就是它的三个参数,在那个命令。 mappend 使用从列表中并行获取的连续三元组值调用此函数。因此 @1list 中获取值,@2(cdr list) 中获取连续值,而 @3 从整数列表中获取连续值。每当 @1 至少与其后继 @2 一样大时,我们将位置索引 @3 收集到 one-element 列表中。 mappend 将它们连接在一起。

与此相反,我们可以编写一个更直接的解决方案,它需要更多代码,但可以更好地利用机器资源:

(defun ascending-partitions (list)
  (let (partition output prev)
    (each ((item list))         ;; use (dolist (item list)  in Common Lisp
      (when (and prev (<= item prev))
        (when partition
          (push (nreverse partition) output)
          (set partition nil))) ;; use setf or setq in Common Lisp
      (push item partition)
      (set prev item))          ;; ditto
    (when partition
      (push (nreverse partition) output))
    (nreverse output)))