LISP: многоуровневая рекурсивная обратная функция - PullRequest
2 голосов
/ 14 сентября 2009

Как перевернуть список так, чтобы каждый подсписок также был перевернут? Это то, что я до сих пор:

(defun REV (L)
  (cond
    ((null L) nil)
    ((listp L)
     (append
      (REV (cdr L))
      (list (car L))))
    (t
     (append
      (REV (cdr L)) 
      (list (car L))))))

Ответы [ 4 ]

5 голосов
/ 14 сентября 2009

Вы находитесь на правильном пути, но ваши два последних условия имеют одно и то же действие, которое должно указывать на то, что одно из них не выполняет то, что должно. На самом деле, второе условие, случай listp, неверно, потому что, когда это список, вам нужно добавить реверс этого списка вместо неизмененного списка. Возможное решение:

(defun reverse (l)
  (cond ((null? l) nil)
        ((listp (car l)) (append (reverse (cdr l)) 
                                 (list (reverse (car l)))))
        (t
          (append (reverse (cdr l)) 
                  (list (car l))))))

>  (reverse '((1 2 3) (4 5 6)))
((6 5 4) (3 2 1))

Как видите, единственное отличие состоит в том, что вы проверяете, является ли первый элемент списком, и если это так, вы переворачиваете первый элемент перед добавлением его.

2 голосов
/ 14 сентября 2009

Я бы написал так:

(defun reverse-all (list)
  (loop
     with result = nil
     for element in list
     if (listp element)
     do (push (reverse-all element) result)
     else do (push element result)
     finally (return result)))
0 голосов
/ 03 января 2017

Ответ dmitry_vk (который, вероятно, быстрее в большинстве lisps, чем использование append в предыдущих примерах) в более упрощенном виде:

(defun reverse-all (list)
  (let ((result nil))
    (dolist (element list result)
      (if (listp element)
          (push (reverse-all element) result)
          (push element result)))))

Или даже:

(defun reverse-all (list)
  (let ((result nil))
    (dolist (element list result)
      (push
        (if (listp element) (reverse-all element) element)
          result))))
0 голосов
/ 14 сентября 2009

Звучит как домашнее задание :) 1001 *

Похоже, вы начали с написания обычного обратного кода. Я дам вам подсказку: второе условие (listp L) не совсем верно (оно всегда будет верным). Вы хотите проверить, является ли что-то еще списком.

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