2014-11-25 1 views
0

Я делал упражнение 2.18 из SICP (структура и интерпретация компьютерных программ, 2-е издание), чтобы сделать программу повернуть вспять список. А вот мой код:Когда бы минусы возвращали каскадный список?

 
(define (rev l) 
    (if (null? (cdr l)) 
    l 
    (cons (rev (cdr l)) (car l)))) 

Когда я тестировал с (rev (list 1 2 3 4 5)), он вернулся:

(((((5) . 4) . 3) . 2) . 1) 

Это было странно для меня. Почему он возвратил каскадный список?

Когда я кладу:

 
(cons 1 
     (cons 2 
      (cons 3 '()))) 

вернулся (1 2 3) но не (((1) 2) 3).


Я делаю упражнение SICP в DrRacket с языком R5RS.

Я делал ошибки или выбирал неправильный язык?

+0

Я не думаю, что вы выбрали неправильный язык, и вы также выбрали очень хорошую книгу. Подсказка: функция, введенная непосредственно перед упражнением 2.18, имеет значение. – molbdnilo

+0

Возможно, было бы полезно прочитать этот вопрос и ответить [Точечная нотация в схеме] (http: // stackoverflow.ком/кв/20216711/1281433). –

ответ

1

Вам нужно узнать, что такое список, и получить интимное отношение к нему, чтобы быть хорошим лизром. Список (1 2 3) только визуальный сахар для пар (1 . (2 . (3 .()))) и могут быть сделаны с (cons 1 (cons 2 (cons 3 '())))

Структура (((((5) . 4) . 3) . 2) . 1) не список, кроме (5), который визуально сахар для (5 .()). Это может быть сделано с (cons (cons (cons (cons (cons 5 '()) 4) 3) 2) 1)

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

Кажется, вы пытаетесь отменить список, и затем просто накапливая список, пока вы итерацию его:

(define (reverse lst) 
    (define (reverse-aux lst acc) 
    (if (null? lst) 
     acc 
     (reverse-aux (cdr lst) (cons (car lst) acc)))) 
    (reverse-aux lst '())) 

Как вы можете видеть, что я определить вспомогательную функцию, чтобы получить третий параметр, а затем использовать Это. Большинство Махинаторы предпочел бы сделать как в одной операции с именем let

(define (reverse lst) 
    (let reverse-aux ((lst lst) (acc '())) 
    (if (null? lst) 
     acc 
     (reverse-aux (cdr lst) (cons (car lst) acc))))) 

Это точно так же. Обычно при создании чего-то итеративного многие используют имя loop вместо reverse-aux, но это может быть любое имя, и я хочу сохранить имя из первого примера.

Нет ярлыка. Вы должны уметь посмотреть ((a b) c (d)) и подумать ((a . (b())) . (c . ((d .()) .()), поэтому вам нужно сделать много упражнений.

На каком языке в DrRacket использовать при выполнении SICP есть look at my previous answer.

+0

'(cons (cons (cons (cons (cons (cons 5 '()) 4) 3) 2) 1)' to '(((((5). 4) 3) 2). 1)' спасибо много –

Смежные вопросы