【问题标题】:How to order a list in sublists in Lisp?如何在 Lisp 的子列表中排序列表?
【发布时间】:2019-06-04 00:38:15
【问题描述】:

我有一个这样的列表:

(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 的新手,需要一些帮助

【问题讨论】:

  • 那么你想每次当前元素低于前一个元素的时候开始一个新的子列表?该描述是否使您更容易弄清楚如何对其进行编码?
  • (4 55 43) 没有升序。
  • @Svante 抱歉,这是一个错误

标签: lisp sublist


【解决方案1】:

这是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),以及从1 开始的递增整数的无限列表由(range 1)制作。

do 宏为我们编写了一个匿名函数,其中嵌入在表达式中的@1@2@3 变量是它的三个参数,按顺序排列。 mappend 使用从列表中并行获取的连续三组值调用此函数。因此@1list 中获取值,@2(cdr list) 中获取连续值,@3 从整数列表中获取连续值。只要@1 至少与其后继@2 一样大,我们就会将位置索引@3 收集到一个元素列表中。 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)))

【讨论】:

  • 非常感谢,这真的很有帮助 我现在明白了一些事情......
猜你喜欢
  • 1970-01-01
  • 2019-11-29
  • 1970-01-01
  • 1970-01-01
  • 2012-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多