Решение упражнения 2.18 из SICP
Для того, чтобы развернуть список, нужно просто перекинуть подряд все элементы списка, начиная с первого, в новый список, причем добавлять каждый последующий элемент в начало строящегося списка.
Этот подход легко реализуется следующей процедурой:
(define (reverse items) (define (reverse-iter source result) (if (null? source) result (reverse-iter (cdr source) (cons (car source) result)))) (reverse-iter items (list)))
Обратите внимание, что вызов (list) в последней строке строит пустой список. Такой же результат можно получить, если заменить в этом месте (list) на null. Возможно, для обозначения null в других диалектах используется другая запись.
Comments
Pingback from SICP по-русски » Blog Archive » Решение упражнения 2.27 из SICP
Date: January 28, 2008, 10:09 pm
[…] Определение процедуры reverse можно посмотреть в решении упражнения 2.18. […]
Comment from tymmym
Date: May 25, 2008, 3:31 pm
Можно использовать процедуру append, описанную до упражнений:
(define (reverse items)
(if (null? (cdr items))
items
(append (reverse (cdr items)) (list (car items)))))
Comment from null-me
Date: February 21, 2009, 11:55 am
Я сделал так. Хотя решение автора, конечно, и изящнее и эффективнее…
(define (reverse items)
(define (proc items count)
(if (> 0 count)
()
(cons (list-ref items count) (proc items (dec count)))))
(proc items (dec (length items))))
Comment from null-me
Date: February 21, 2009, 11:56 am
(dec - декремент)
Comment from JessicaFletcher
Date: March 7, 2009, 1:25 pm
еще один простой способ -
(define (reverse item)
(if (= (cdr item) nill)
(item)
(cons (reverse (cdr item)) (car item))))
Comment from anonymous
Date: November 29, 2010, 10:28 am
простой и неверный:
‘(((((25) . 16) . 9) . 4) . 1) это вовсе не ‘(25 16 9 4 1)
Comment from Kirill
Date: April 24, 2012, 7:23 pm
Будет верный, если чуть подправить:
(define (reverse item)
(if (null? (cdr item))
item
(append (reverse (cdr item)) (list (car item)))))
Хотя таким образом получается более худший способ, чем описанный в 1 комментарии(достаточно передать пустой список). И все равно, у автора решение лучше: итерация и cons(вычислительная сложность — n), а тут рекурсия и append(вычислительная сложность — n**2, который перебирет каждый раз весь список для вставки значения.
Write a comment