Как заказать список в подсписках в Лиспе? - PullRequest
0 голосов
/ 04 июня 2019

У меня есть список, подобный этому:

(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 и нуждаюсь в помощи

1 Ответ

2 голосов
/ 04 июня 2019

Вот одно из возможных решений в 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 вызывать эту функцию с последовательными тройками значений, взятых из списков параллельно. Таким образом, @1 принимает значения из list, @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)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...