LISP: обращение списка в LISP с использованием RPLACA/RPLACD/NCONC

Итак, я пытаюсь заставить функцию принимать список и переворачивать его на место, но я не уверен, как бы я использовал RPLACA/RPLACD/NONC. В основном делает то же самое, что и reverse, но использует узлы cons исходного списка и не выделяет новые узлы cons. Что у меня есть до сих пор

(defun rip(lst)
(cond   (( null lst) 0)
    ((eq (nil) (cdr (last lst))) 1)
    (((setq x (car (last lst)))
     (rplaca (car (last lst)) (car first lst))
     (rplaca (car first lst) x)) + 2 rip(butlast(rest lst)))))

person John    schedule 17.02.2015    source источник
comment
Добро пожаловать в stackoverflow.com. Похоже, вы пытались написать какой-то код самостоятельно. Вы должны включить это в вопрос, даже если он неполный. Это дает нам отправную точку и показывает, что вы приложили усилия.   -  person genisage    schedule 17.02.2015
comment
До сих пор я не использовал ни одну из необходимых функций. (defun reverse-in-place (l) (let ((result l)) (recurse reving ((ll) (r (reverse l)) (cond ((not (consp l)) результат) (else (setf (car л) (автомобиль r)) (оборот (cdr л) (cdr r)))))))   -  person John    schedule 17.02.2015
comment
@John Вы уверены, что используете Common Lisp? Я не думаю, что ни recurse, ниreving не существуют в языке.   -  person zck    schedule 17.02.2015
comment
Извините, я добавил не тот тег   -  person John    schedule 17.02.2015
comment
@zck: RECURSE — это макрос, используемый, например, в книге Land of Lisp. REVING — это имя, представленное здесь во фрагменте кода.   -  person Rainer Joswig    schedule 17.02.2015
comment
Я не уверен, что вы тот же анонимный автор (теперь удаленный) lisp на месте переворачивания списка (требования очень похожи: реверсирование списка на месте с использованием RPLACA/RPLACD/NONC). Если да, то я пропустил часть вашего вопроса в одном из своих комментариев (извините!), но это намного лучшая формулировка вопроса и включает некоторые попытка кода. Хорошее улучшение или новый старт, если вы новичок, и это был не ваш вопрос!   -  person Joshua Taylor    schedule 17.02.2015
comment
Я думаю, что это был аналогичный вопрос, но я не могу видеть сообщение. Вы случайно не знаете, что это был за пост? Извините, я новичок в этом   -  person John    schedule 17.02.2015
comment
@John Это было так: i.stack.imgur.com/yFJIm.png . Это был не очень хороший вопрос, но анонимный пользователь, похоже, в ярости удалил вопрос, когда я (по общему признанию) что-то пропустил в вопросе. Однако содержание вопроса было практически идентичным (за исключением кода). Это домашнее задание? Возможно, это был кто-то из ваших одноклассников. :)   -  person Joshua Taylor    schedule 18.02.2015
comment
@JoshuaTaylor Я думаю, что это одноклассник. До сих пор я сделал следующее, но я не уверен, что это на уровне. Мысли? (defun rip(lst) (cond (( null lst) 0) ((eq (nil) (cdr (last lst))) 1) (((setq x (car (last lst))) (rplaca (car (last лст)) (первая машина лст)) (рплаца (первая лст машина) х)) + 2 рип(бутласт(остальные лст)))))   -  person John    schedule 18.02.2015


Ответы (2)


Таким образом, потенциальным аргументом списка будет (1 2). Мы могли бы представить, что аргумент относится к списку с адресом #A и что он выглядит так:

#A=(1 . #B)
#B=(2 . nil) 

Для каждого минуса мы создаем локальную переменную, хранящую cdr, прежде чем установить cdr в предыдущее cons, которое равно нулю для первого cons. Когда текущий cons равен nil, все готово, и результатом будет предыдущий cons. Результатом для нашего примера будет:

#A=(1 . nil)
#B=(2 . #A) 

Единственная изменяющая функция, которая вам понадобится, это rplacd, поскольку единственное, что изменяется, это cdr. Функция может выглядеть примерно так:

(defun nreverse (list)
  (labels ((aux (list prev)
             (if (endp list)
                 <??>
                 (let ((next <??>))
                   (rplacd <??> <??>)
                   (aux <??> <??>)))))
    (aux list nil)))

Или, если вы не против утечки, вы можете сделать это:

(defun nreverse (list &optional prev)
  (if (endp list)
      <??>
      (let ((next <??>))
        (rplacd <??> <??>)
        (nreverse <??> <??>))))
person Sylwester    schedule 18.02.2015

Поэтому я считаю, что это был ответ, который они искали:

Recursive: 
(define rip (lst)
(if (null lst) nil (nconc (rip (rest lst))(rplacd lst nil))))

Non-Recursive:
(defun rip (lst)
(do ((res nil) (todo (rest lst)(rest lst)))
    ((null lst) res)
  (setf res (rplacd lst res))
  (setf lst todo) ))
person John    schedule 26.02.2015