Схема функции точечного произведения двух списков

#scheme #racket

#схема #ракетка

Вопрос:

Я пытаюсь определить функцию точечного продвижения, которая принимает два списка в качестве параметров и применяет версию точечного произведения, принимая x1 * y1 x2 * y2 и так далее. Я заставил его работать с пустым списком, но это все. Спасибо.

     (define (dot-prod l1 l2)
      (cond ((or (null? l1)(null? l2)) '())
            (else
             (cons (* (car l1) (car l2))
                   (* (cdr l1) (cdr l2))))))
  

Ответ №1:

Это идеально подходит для использования встроенных процедур. Предполагая, что списки имеют одинаковую длину:

 (define (dot-prod l1 l2)
  (apply   (map * l1 l2)))
  

Но если вы хотите написать решение с нуля, вы должны:

  1. Возвращает значение, которое имеет смысл для базового варианта — если это дополнение, мы хотим, чтобы там был ноль, а не пустой список, мы не создаем новый список в качестве выходных данных
  2. Вызовите dot-prod процедуру на рекурсивном шаге, о чем вы полностью забыли
  3. Объедините результат осмысленно — опять же, если мы выполняем сложение, мы хотим использовать не cons

Это то, что я имею в виду:

 (define (dot-prod l1 l2)
  (cond ((null? l1) 0)
        (else
         (  (* (car l1) (car l2))
            (dot-prod (cdr l1) (cdr l2))))))
  

В любом случае, это работает так, как ожидалось:

 (dot-prod '(1 2 3) '(4 5 6))
=> 32
  

Комментарии:

1. Я бы сказал, что это (foldl (map * l1 l2)) лучше, чем использовать apply здесь.

2. Я думаю, что foldl нужны три параметра.

Ответ №2:

цикл ‘for / sum’ может быть использован здесь для простой понятной функции. Если l и k — это 2 списка:

 (define (dotproduct l k)
  (for/sum ((i l)(j k))
    (* i j)))
  

Тестирование:

 (dotproduct '(1 2 3) '(4 5 6))
; =>32
  

Это также может быть изменено, если значения (x y) представлены в виде списка списков:

 (define (f l)
  (for/sum ((i l))
    (apply * i)))

(f '((1 4)(2 5)(3 6)))
; => 32
  

Метод также может быть расширен, если необходимо вычислить x, y, z или даже больше значений.