Как я могу создать n мерный список? - PullRequest
0 голосов
/ 21 января 2019

Как начинающий, я борюсь с губами, в моей программе у меня есть список вроде:
(((NIL (B) (C) (B)) (A)) (E) (G))

Но я хочу построить n-мерный список (в данном случае 3-dim):

((B C B)(A)(E G))

Я попытался сгладить список, но он не выглядит правильным.Я буду признателен за любую помощь.

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Это работает для меня:

(defun peculiar-transform (input-list)
  (destructuring-bind (((ignore (xb) (xc) (xb)) (xa)) (xe) (xg)) input-list
    `((,xb ,xc ,xb) (,xa) (,xe ,xg))))

Тест:

[1]> (peculiar-transform '(((NIL (B) (C) (B)) (A)) (E) (G)))
((B C B) (A) (E G))
[2]> (peculiar-transform '(((NIL (2) (3) (2)) (1)) (5) (7)))
((2 3 2) (1) (5 7))

Я переименовал ваши переменные в XA, XB, ... просто чтобы уменьшить путаницу, когда мы используем A, B, ..., встречающиеся во входном тестовом примере.

Здесь мы используем destructuring-bind для непосредственного использования вашего шаблона ввода (только с переименованными переменными) в качестве спецификации для извлечения элементов, а затем мы используем синтаксис обратной кавычки для создания шаблона, который имеет требуемый вывод форма, с извлеченными частями, вставленными в правильные места.

0 голосов
/ 21 января 2019

Поскольку вы на самом деле не дали спецификации того, для чего предназначена ваша программа, вот что-то, что превращает вашу структуру в ту, которую вы хотите, в предположении, что что-то еще дает вам эту структуру.

Ваша структура - это минусы, автомобиль которых либо нулевой, если структуры больше нет, либо структура.CDR структурного списка одноэлементных списков, и нам нужны эти элементы.

Я назвал структуру BLOB-TREE, и каждый CDR является BLOB.

(defun blob-to-list (blob)
  ;; a blob is a list of single-element lists, and we want the elements
  (mapcar (lambda (e)
            (assert (and (listp e) (null (rest e))))
            (first e))
          blob))

(defun blob-tree-to-list (blobs)
  ;; BLOB-TREE is some horrible tree: what we need to do is split it into
  ;; its car & cdr, and then convert the cdr to a list with
  ;; blob-to-list, then recurse on the car, until we get a null car.
  (labels ((extract-blobs (remains accum)
             (etypecase remains
               (null accum)
               (cons
                (extract-blobs (car remains) (cons (blob-to-list (cdr remains))
                                                   accum))))))
    (extract-blobs blobs '())))

Исейчас

> (blob-tree-to-list '(((NIL (B) (C) (B)) (A)) (E) (G)))
((b c b) (a) (e g))

Я скорее сомневаюсь, что это именно то, что вы хотите сделать.


В качестве проверки я написал функцию, которая принимает список в нужной вам форме ипревращает его в блоб-дерево.Вы можете использовать это, чтобы проверить, что все происходит в правильном направлении.

(defun list-to-blob-tree (l)
  (labels ((list-to-blob (es)
             (mapcar #'list es))
           (build-blob-tree (tail accum)
             (if (null tail)
                 accum
               (build-blob-tree (rest tail)
                                (cons accum (list-to-blob (first tail)))))))
    (build-blob-tree l '())))

Если вы действительно хотите иметь дело с такими вещами (что в реальной жизни вам иногда приходится), хорошийПодход состоит в том, чтобы написать набор функций доступа, которые позволят вам абстрагироваться от непонятных структур данных, которые вам были предоставлены.

В этом случае мы можем написать функции для работы с BLOB-объектами:

;;; Blobs are lists are lists where each element is wrapped in a
;;; single-element list

(defun blob->element-list (blob)
  ;; a blob is a list of single-element lists, and we want the elements
  (mapcar (lambda (e)
            (assert (and (listp e) (null (rest e))))
            (first e))
          blob))

(defun element-list->blob (list)
  ;; turn a list into a blob
  (mapcar #'list list))

И еще один набор функций для работы с деревьями BLOB-объектов, которые (оказывается) - это просто списки, построенные с заменой их машин и CDR:

;;; Blob trees are lists, built backwards
;;;

(deftype blob-tree ()
  '(or cons null))

(defconstant null-blob-tree nil)

(defun blob-tree-car (blob-tree)
  (cdr blob-tree))

(defun blob-tree-cdr (blob-tree)
  (car blob-tree))

(defun blob-tree-cons (car cdr)
  (cons cdr car))

(defun blob-tree-null-p (blob-tree)
  (null blob-tree))

В обоих случаях я написал только те функции, которые мне нужны: есть читатели, но нет писателей, например.

И теперь мы можем написать функции, которые нам нужны в терминах этих абстракций:

(defun blob-tree->element-list (blob-tree)
  (labels ((extract-blobs (tree accum)
             (assert (typep tree 'blob-tree))
             (if (blob-tree-null-p tree)
                 accum
               (extract-blobs (blob-tree-cdr tree)
                              (cons (blob->element-list (blob-tree-car tree))
                                    accum)))))
    (extract-blobs blob-tree '())))

(defun element-list->blob-tree (el)
  (labels ((build-blob-tree (elt accum)
             (if (null elt)
                 accum
               (build-blob-tree (rest elt)
                                (blob-tree-cons
                                 (element-list->blob (first elt))
                                 accum)))))
    (build-blob-tree el null-blob-tree)))

Это означает, что если представление изменяет эти два мягковолосатые функции не делают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...