如何在 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
使用从列表中并行获取的连续三元组值调用此函数。因此 @1
从 list
中获取值,@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)))
我有一个这样的列表:
(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)
.
do
宏为我们写了一个匿名函数,其中表达式中嵌入的@1
、@2
和@3
变量就是它的三个参数,在那个命令。 mappend
使用从列表中并行获取的连续三元组值调用此函数。因此 @1
从 list
中获取值,@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)))