如何在Lisp的子列表中排序列表? [英] How to order a list in sublists in Lisp?

查看:397
本文介绍了如何在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用从列表中并行获取的连续三重值调用此函数.因此@1list获取值,@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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆