2016-10-19 4 views
0

Ich versuche, eine Dot-Prod-Funktion zu definieren, die zwei Listen als Parameter nimmt und die Punktproduktversion anwendet, indem x1 * y1 + x2 * y2 und so weiter nimmt. Ich habe es mit einer leeren Liste arbeiten lassen, aber das ist es. Vielen Dank.Scheme Punkt Produktfunktion von zwei Listen

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

Antwort

2

Dies ist perfekt für die Verwendung von integrierten Verfahren. Unter der Annahme, dass die Listen gleicher Länge haben:

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

Aber wenn Sie wollen, eine Lösung von Grund auf neu zu schreiben, müssen Sie:

  1. Return ein Wert, der Sinn für den Basisfall macht - wenn es eine Ergänzung ist wollen wir eine Null gibt, nicht eine leere Liste, wir eine neue Liste als Ausgabe nicht bauen
  2. Rufen Sie die dot-prod Prozedur in dem rekursiven Schritt, etwas, das Sie völlig vergessen
  3. das Ergebnis nach Bedeutung Combine - wieder, wenn wir machen eine Ergänzung Wollen wir + nicht cons

Das ist, was ich meine verwenden:

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

So oder so, es funktioniert wie erwartet:

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

Ich würde sagen, dass '(foldl + (map * l1 l2))' 'ist besser als mit 'apply' hier. –

1

'für/sum' Schleife kann sein hier für eine einfache verständliche Funktion verwendet. Wenn l und k 2 sind:

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

Testing:

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

Dies auch dann, wenn (xy) modifiziert werden können, Werte auftreten als eine Liste von Listen:

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

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

Verfahren ist auch erweiterbar, wenn x, y, z oder noch mehr Werte ausgewertet werden sollen.