#recursion #scheme #racket
Вопрос:
Учитывая два списка одинаковой длины, вычислите сумму больших чисел в каждой соответствующей паре чисел (с одинаковым индексом) из списков без использования каких-либо встроенных функций, лямбда или набора!. Например, учитывая эти два списка:
список А: (5 3 -4 6 10)
список В: (4 4 9 6 4)
Большие числа каждой пары чисел являются:
больший список: 5, 4, 9, 6, 10
Таким образом, сумма составляет 34. Мой код таков :
(define (sum list1 list2)
(cond ((null? list1) 0)
((null? list2) 0)
((>= (car list1) (car list2))
( (car list1) (sum (cdr list1) (cdr list2)))
( (car list2) (sum (cdr list1) (cdr list2)))
)
)
)
Я сталкиваюсь с разными ошибками для разных входных данных:
(сумма ‘(5) ‘(3)) 3 —-противоположность тому, что необходимо (сумма ‘(5) ‘(13)) —-нет вывода (сумма ‘(5 1) ‘(3 12)) . . : ожидаемое нарушение контракта: номер? дано: # —-ошибка
Правильный вывод-это
(sum '(1 9 0) '(-5 6 10))
> 20
Комментарии:
1. Вы пытаетесь добавить
#f
к числу. Как это должно работать?2. Заменить
#f
на0
3. Существует также проблема с заключительным пунктом вашего
cond
.4. Чтобы быть более ясным: у вас нет оснований для
(< (car list1) (car list2))
. Ваше последнее предложение содержит два выражения значений, отбрасывает значение( (car list1)...
, и в результате получается( (car list2) ...
Ответ №1:
Я не уверен, что не считается встроенной функцией.
(define (sum L1 L2)
(if (null? L1)
0
( (if (> (car L1) (car L2))
(car L1)
(car L2))
(sum (cdr L1) (cdr L2)))))
Примерно так мало, как я могу получить.
Ответ №2:
Ты забыл else
в своем cond
—
(define (sum list1 list2)
(cond ((null? list1) 0)
((null? list2) 0)
((>= (car list1) (car list2))
( (car list1) (sum (cdr list1) (cdr list2))))
(else ( (car list2) (sum (cdr list1) (cdr list2))))))
Вот еще один способ написать это —
(define (max a b)
(if (> a b) a b))
(define (sum a b)
(if (or (null? a) (null? b))
0
( (max (car a) (car b))
(sum (cdr a) (cdr b)))))
Ответ №3:
Когда у вас нет else
пункта, реализация схемы может свободно выбирать то, что кажется подходящим. Похоже, ваша реализация возвращает что-то, что не является числом.
Вот ваш код со вставленной неопределенностью:
(define (sum list1 list2)
(cond ((null? list1) 0)
((null? list2) 0)
((>= (car list1) (car list2))
;; the code line below is dead code. It is the last
;; expression that is the tail call and result
( (car list1) (sum (cdr list1) (cdr list2))) ; dead
( (car list2) (sum (cdr list1) (cdr list2))))
;; this is what hapens when the first element of
;; list1 is smaller than the first element of list2
(else 'i-choose-you-pikachu)))
Так что вместо #<void>
того, когда вы проходите его (sum '(1) '(2))
, вы получаете i-choose-you-pikachu
, и это не число. Так что, если вы передадите его (sum '(2 1) '(1 2))
, это сработает ( 1 'i-choose-you-pikachu)
, и это должно сигнализировать об ошибке от R6RS и новее, в то время как в R5RS свиньи могут летать, так как стандарт на самом деле не охватывает такие случаи напрямую.
Также обратите внимание, что он занимает не самое большое место в третьем сроке, а самое маленькое… (sum '(2 2 2 2) '(1 1 1 1)) ; ==> 4
Итак, вы хотите обработать последствия для каждого термина, а затем добавить else
термин для последней позиции:
(define (sum list1 list2)
(cond ((null? list1) 0)
((null? list2) 0)
((>= (car list1) (car list2))
( (car list1) (sum (cdr list1) (cdr list2))))
(else
( (car list2) (sum (cdr list1) (cdr list2))))))
Также обратите внимание, что отступ указывает на то, что термины и заключительные скобки из вашего вопроса были пустыми. Если вам нужно сопоставить их таким образом, вы используете неправильный редактор!