Denkfehler bei map?!

Benutzeravatar
bearmann
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 121
Registriert: 20. Okt 2006 13:53
Wohnort: Darmstadt
Kontaktdaten:

Denkfehler bei map?!

Beitrag von bearmann »

Grüßt euch,
ich steh mit map irgendwie auf dem Kriegsfuß!
Syntax ist ja (map <function> <list>) und map wendet nun die Funktion auf jedes Element der List an, richtig?!

Nun hab ich - zum Verständnis - mal eine Funktion gebastelt, die eigentlich einfach jedes Element der Liste mit einer Konstanten multiplizieren soll.
Aus '(1 2 3) soll dann z.B. (bei x = 5), '(5 10 15) werden.
Hier mein Code...

Code: Alles auswählen

(define (map1 X1 alon)
  (map 
      (local ((define (mul a b) (* a b))) (mul X1 alon)) 
   alon))

(map1 5 (list 3 2 1))
Spuckt mir aber den Fehler aus, dass MUL zwei Zahlen erwartet (was ja auch richtig ist) aber eine Zahl und eine Liste bekommt ... was macht also map?! Gar nichts, wie es scheint?!
Ich glaube, mein Fehler liegt beim expression-Teil von (local...), also (mul X1 alon) ... aber ich kriegs einfach nicht hin! :(

Würde mich über Aufklärung und Hilfe sehr freuen!

Good night and good luck.
bearmann

quanz
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 103
Registriert: 1. Okt 2007 19:32

Beitrag von quanz »

Code: Alles auswählen

(define (map1 X1 alon)
  (local
      ((define (mul a) 
         (* a X1))
      )
     (map mul alon)
    ))
Probiere es mal damit!

Stumpf.Alex
Nerd
Nerd
Beiträge: 643
Registriert: 1. Okt 2007 12:40
Wohnort: Darmstadt
Kontaktdaten:

Beitrag von Stumpf.Alex »

Jo, das dürfte funktionieren. Der Trick bei map ist einfach, dass map deiner Funktion f nur einen Parameter gibt, nämlich das aktuell betrachtete Element. Möchtest du einen zweiten Parameter haben, muss der außerhalb von deiner mul-Funktion sichtbar für die Funktion definiert werden. Deshalb macht man mul auch local.

Benutzeravatar
bearmann
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 121
Registriert: 20. Okt 2006 13:53
Wohnort: Darmstadt
Kontaktdaten:

Beitrag von bearmann »

Ahhh, besten Dank an euch beide! Dank deines Beispiels, hab ichs nun kapiert, quanz! :)

Wie du sagtest, Alex ... meine lokale Funktion kriegt nur das aktuelle Element der Liste von map übergeben und den anderen kriegt sie aus der übergeordneten Funktion.

Bin nun noch am Basteln, wie ich das z.B. mit zwei Listen mache... also z.B. wenn eine Liste mit einer anderen multipliziert werden soll... Mal schaun.

Besten Dank jedenfalls soweit! :)

Schönes WE an alle,
bearmann

ChRiZz88
Mausschubser
Mausschubser
Beiträge: 87
Registriert: 7. Nov 2007 18:09
Kontaktdaten:

Beitrag von ChRiZz88 »

Hmm, also mein Problem ist, dass ich glaube ich map im Zusammenhang mit Rekursion noch nicht verstanden habe...
Also das Beispiel aus der Vorlesung ist ja das hier:

Code: Alles auswählen

(define (square x)
  (* x x))

(define (square-list list)
  (map
   square list))

(square-list '(1 2 3 4 5))

Das heißt, dass '(1 2 3 4 5) dann '(1 4 9 16 25) ergeben soll. Das ganze ist ja verständlich und einfach. Wie siehts aber aus, wenn zum Beispiel der Wert x in der Liste x mal mit sich multipliziert werden soll? D.h. bei 3 z.B. nicht 3², sondern 3³ und bei 4 eben 4^4...
Würde dann bei '(1 2 3 4 5) --> '(1 4 27 256 3125) ergeben.. Mal angenommen, ich will das nicht mit (expt x x) lösen, weil das zu einfach is, wie sähe das dann in Scheme aus?

Benutzeravatar
bearmann
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 121
Registriert: 20. Okt 2006 13:53
Wohnort: Darmstadt
Kontaktdaten:

Beitrag von bearmann »

Grüß dich,
du musst für das potenzieren eigentlich nur deine Rechenoperation ändern ...
also statt (* x x) eben x^x. Das funktioniert in Scheme nur nicht mit ^x, sondern mit (expt x y). Drück in Scheme mal F1 für die Hilfe und gib unten "expt" ein.
Weiter musst du nichts an deiner Funktion ändern. :)

Grüße,
bearmann

Stumpf.Alex
Nerd
Nerd
Beiträge: 643
Registriert: 1. Okt 2007 12:40
Wohnort: Darmstadt
Kontaktdaten:

Beitrag von Stumpf.Alex »

@ChRiZz88: Nein das brauchst da nich weil, du ja nur dafür einen Parameter brauchst und das ist x selbst. Du könntest das also so implementieren:

Code: Alles auswählen

(define (expt* x) (expt x x))

(map expt* '(1 2 3 4 5))
Du kannst expt* natürlich auch lokal definieren und aufrufen, falls diese Funktion nur dort einmalig gebraucht wird.

PS: Du kannst dir den Code rauskopieren. Der funktioniert so.

ChRiZz88
Mausschubser
Mausschubser
Beiträge: 87
Registriert: 7. Nov 2007 18:09
Kontaktdaten:

Beitrag von ChRiZz88 »

Ist ja klar, aber mal angenommen, ich will expt nicht verwenden? Weil bei der insert-everywhere Aufgabe funktioniert das eben so einfach nicht ;)

Stumpf.Alex
Nerd
Nerd
Beiträge: 643
Registriert: 1. Okt 2007 12:40
Wohnort: Darmstadt
Kontaktdaten:

Beitrag von Stumpf.Alex »

Dann musst du dir eine Hilfsprozedur schreiben. Probiers mal damit:

Code: Alles auswählen

(define (my-expt x y)
  (cond
    [(zero? y) 1]
    [(< y 0) (my-expt (/ 1 x) (abs y))]
    [else (* x (my-expt x (- y 1)))]))

(define (expt* x) (my-expt x x))

(map expt* '(1 2 3 4 5))
Wem eine elegantere Methode einfällt..her mit!

Antworten

Zurück zu „Archiv“