#list #scheme
#Список #схема
Вопрос:
(define (minim lst)
(COND
((NULL? (CDR lst)) (CAR lst))
(< (CAR lst) (minim (CDR lst)) (CAR lst))
(ELSE (minim (CDR lst))))
)
(minim ‘(3 4 2 9 3 8))
3
Я выяснил, что это вторая строка, которая вычисляется и возвращает (CAR любого списка). Чего мне не хватает?
Ответ №1:
Во втором условии вам не хватает круглой скобки. Это заставляет оператор «<» работать с тремя элементами, а не с двумя. Правильный код выглядит следующим образом:
(define (minim lst)
(cond ((null? (cdr lst)) (car lst))
((< (car lst) (minim (cdr lst))) (car lst))
(else (minim (cdr lst)))) )
(minim '(3 4 2 9 3 8))
Однако одно замечание: этот код не является хвостовой рекурсией. Оно проходит весь путь до конца списка и начинает сравнение оттуда (т. Е. последний элемент сравнивается с предыдущим и так далее).
Более эффективная реализация сравнивала бы первый элемент с текущим минимумом, а затем продолжала бы обрабатывать более короткий список каждый раз. Если вы пойдете этим путем, вам понадобится дополнительный аргумент функции, содержащий текущий минимум (это эквивалентно левому сгибу, а не правому сгибу, который вы реализовали).
Комментарии:
1. Вы правы по обоим пунктам. Кроме того, я дважды разбираю список как есть (для сравнения и возврата значения). Спасибо!