В простом скрипте для возврата минимума списка в scheme моим решением возвращается только первое значение списка. В чем ошибка?

#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. Вы правы по обоим пунктам. Кроме того, я дважды разбираю список как есть (для сравнения и возврата значения). Спасибо!