(define (Durchschnitt ...)) in Lisp
Ich bin nur spielen, um mit scheme/lisp und darüber nachgedacht, wie ich den richtigen meine eigene definition von average
. Ich bin mir nicht sicher, wie zu tun, einige Dinge, die ich denke, sind erforderlich, wenn.
- definieren Sie eine Prozedur nimmt eine beliebige Anzahl von Argumenten
- zählen diese Argumente
- übergeben Sie die Liste der Argumente für ( + ), um die Summe zusammen
Hat jemand ein Beispiel für die Definition average
? Ich weiß nicht scheinen, um genug wissen über LISP zu bilden, eine web-Suche, bekommt die Ergebnisse zurück, die ich Suche.
- Dies ist keine Hausaufgabe (habe downvoted aus irgendeinem Grund... wahrscheinlich, weil jemand dachte, es war). Ich arbeite durch die SICP natürlich online und ich war nur Herumspielen mit LISP Frage mich, wie man erstellen Sie diese Zeit des Verfahrens.
- (FWIW, das war ziemlich klar-fast alle Kurse gehen über Funktionen mit rest-Argumente.)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die definition würde eine sehr einfache one-liner, aber ohne Sie zu verderben, Sie in Aussehen sollte:
einer "rest" - argument -- dieser
(define (foo . xs) ...xs...)
definiertfoo
als eine Funktion, die eine beliebige Anzahl von Argumenten und gibt Sie als eine Liste, die den Wert vonxs
.length
gibt die Länge einer Liste.apply
nimmt eine Funktion und eine Liste von Werten und wendet die Funktion auf diese Werte.Wenn Sie bekommen, dass Sie gehen können für mehr:
sehen die
foldl
- Funktion vermeiden Sie die Anwendung eine Liste auf eine potenziell sehr große Liste (dies kann die Sache in manchen Implementierungen, in denen die Länge der Liste der Argumente ist begrenzt, aber es würde nicht viel Unterschied im Schläger).beachten Sie, dass die Schläger hat genau rationals, und Sie können
exact->inexact
in eine bessere floating-point-version.Und die Spoiler sind:
(define (average . ns) (/(apply + ns) (length ns)))
Machen es erforderlich sein, dass ein argument:
(define (average n . ns) (/(apply + n ns) (add1 (length ns))))
Verwenden
foldl
:(define (average n . ns) (/(foldl + 0 (cons n ns)) (add1 (length ns))))
Machen es verwenden, floating point:
(define (average n . ns) (/(foldl + 0.0 (cons n ns)) (add1 (length ns))))
In Common Lisp, es sieht aus wie Sie tun können:
ich habe zwar keine Ahnung, ob
&rest
ist auf alle Implementierungen von Lisp. Referenz hier.Setzen, dass code in GNU CLISP Ergebnisse in:
3,5 (richtig).
null
,undefined
,nan
etc), aber meistens es ist besser, dass der code einen Fehler auslösen, früher, anstatt Sie zu verbreiten, eine möglicherweise falsche Ergebnis durch.%
Klammer-matching hatte ich zu tun in vi.(
ohne schließen)
, so source code ist nie unsymmetrisch, was bedeutet, dass Sie nie brauchen, Sie zu zählen -- und das ist praktisch in allen Sprachen. (Aber natürlich nicht aufhören, die üblichen Klammer-bezogene Witze...)Beiden Versionen in Common Lisp:
Schema, ziehe ich mit Hilfe einer Liste, statt die "rest" - argument, weil rest-argument vereinfacht die Implementierung von Verfahren, wie die folgenden schwer:
Verpackung beliebige Anzahl von Argumenten in einer Liste können Sie eine Liste Vorgang auf die Argumente. Sie können mehr tun mit weniger syntax und Verwirrung. Hier ist mein Schema version
average
dass take 'n' Argumente:Hier wird das gleiche Verfahren in Common Lisp:
apply
für die übersetzung von Liste in einer Liste von Argumenten.(Incf sum n)
ist besser als(setf sum (+ sum n))
. Außerdem meinen ersten Prototyp in der Regel wäre(/ (reduce #'+ list) (length list))
, und dann könnte ich es ändern um eine(loop for element in list counting element into length summing element into sum finally (return (/ sum length)))
.average
so würde es Aussehen:(define (call-average . ns) (average (unpack ns)))
? Ich bin derzeit ein Scheme/Lisp-Neuling, also ich weiß ehrlich nicht, wie möglich das ist.In R5RS Scheme: