如何在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完全陌生,需要一些帮助
I think you can guess the order, it has an ascending order, I'm totally new with Lisp and need some help
推荐答案
以下是 TXR 中的一种可能的解决方案. Lisp:
Here is one possible solution in TXR Lisp:
(defun ascending-partitions (list)
(let ((indices (mappend (do if (>= @1 @2) (list @3))
list (cdr list) (range 1))))
(split list indices)))
我们获得列表中元素的数字索引位置,这些位置不大于其前任元素;然后我们使用 split
函数将列表切成碎片在这些索引上.
We obtain the numeric index positions of the elements in the list which are not greater than their predecessors; then we use the split
function to cut the list into pieces at these indices.
通过通过 mappend
函数:原始的list
,与删除了第一个元素的相同列表(cdr list)
平行,以及由(range 1)
生成的从1开始的无限整数递增列表.
Calculating the indices is done by processing three lists through the mappend
function: the original list
, in parallel with that same list with the first element removed (cdr list)
, and an infinite list of incrementing integers starting at 1 produced by (range 1)
.
do
宏为我们编写了一个匿名函数,其中嵌入在表达式中的@1
,@2
和@3
变量是按顺序排列的三个参数. mappend
用从列表中并行获取的连续三重值调用此函数.因此@1
从list
获取值,@2
从(cdr list)
获取连续值,并且@3
从整数列表中获取连续值.每当@1
至少与其后继@2
一样大时,我们会将位置索引@3
收集到一个元素列表中. mappend
将这些链接在一起.
The do
macro writes an anonymous function for us, in which the @1
, @2
and @3
variables embedded in the expression are its three arguments, in that order. mappend
call this function with successive triplets of values taken from the lists in parallel. Thus @1
takes values from list
, @2
takes successive values from (cdr list)
and @3
takes successive values from the list of integers. Whenever @1
is at least as large as its successor @2
, we collect the positional index @3
into a one-element list. mappend
catenates these together.
与此相反,我们可以编写一个更直接的解决方案,该解决方案需要更多的代码,但可以更好地利用机器资源:
In contrast to this, we could write a more direct solution that requires more code, but makes better use of machine resources:
(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)))
这篇关于如何在Lisp的子列表中排序列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!