2016-04-06 2 views
0

Я попытался изменить список в схеме, используя самую основную концепцию, которую я имел о cons, cdr, car. Здесь l-orig - это список, подлежащий обращению, и l-count действует как счетчик.Scheme lisp cons и список

Мой код здесь идет:

(define (rev l-orig l-count) 
(
    if (null? l-count) 
    (cons l-orig '()) 
    (rev (cons (cdr l-orig) (car l-orig)) (cdr l-count)) 
) 
) 
(display (rev '(1 2 3 4 5) '(1 1 1 1 1))) 

И выход (((2 3 4 5) . 1)) Честно говоря, я новичок в лепет, и мне нужна простая помощь здесь. Если я намереваюсь использовать этот метод, может ли кто-нибудь предложить мне правильный способ сделать это?

+0

связанные ?: https://stackoverflow.com/questions/19529829/how-to-recursively-reverse- a-list-using-only-basic-operations/19536834 # 19536834 –

ответ

1

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

(define (rev l-orig l-count) 
    (if (null? l-orig) 
     l-count 
     (rev (cdr l-orig) (cons (car l-orig) l-count)))) 

Обратите внимание, что аккумулятор начинает как пустой список, который идеально подходит для cons ИНГ каждого нового элемента к нему: ответ

(rev '(1 2 3 4 5) '()) 
=> '(5 4 3 2 1) 
+0

Это решение легко приемлемо. Но моя цель - получить перевернутый список в самом l-orig. Я просто хочу использовать l-count в качестве счетчика. Любая помощь по этому поводу? –

+0

Не надо. В Scheme мы стараемся избегать модификации ввода, вместо этого мы предпочитаем строить новый вывод, это способ функционального программирования. –

0

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

(define (rev xs) 
    (rev-accum xs '())) 

(define (rev-accum xs accum) 
    (if (null? xs) 
     accum 
     (rev-accum (cdr xs) (cons (car xs) accum)))) 
Смежные вопросы