Схема — Больший список из 2 списков и его сумма

#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))))))
 

Также обратите внимание, что отступ указывает на то, что термины и заключительные скобки из вашего вопроса были пустыми. Если вам нужно сопоставить их таким образом, вы используете неправильный редактор!