2009-12-18 6 views
5

Was ist das exklusive oder Funktionen im Schema? Ich habe versucht xor und ^, aber beide geben mir einen ungebundenen lokalen Variablenfehler.Exclusive OR in Schema

Googeln fand nichts.

+0

Möchten Sie bitweise exklusiv oder? – Brian

+0

Ich arbeite mit speziell booleschen (#t und #f), so lange es richtig auf Boolean funktioniert, bin ich gut –

+0

Eigentlich denke ich nicht gleich funktioniert in diesem Fall, aber ich kann nicht herausfinden, was das ist entweder? Ich habe versucht! = Und/= –

Antwort

8

Ich schlage vor, Sie (not (equal? foo bar)) verwenden, wenn nicht funktioniert gleich. Bitte beachten Sie, dass es schnellere Komparatoren für Ihre Situation wie eq?

+0

Also Scheme bietet nicht eine nicht gleich Funktion? Sie müssen selbst mit nicht rollen und (= | eq? | Gleich?)? –

+5

Schema ist eine ziemlich minimalistische Sprache. Von R RS: "Programmiersprachen sollten nicht durch Stapelfunktion über Feature, sondern durch die Beseitigung der Schwächen und Einschränkungen, die zusätzliche Funktionen erscheinen notwendig gemacht werden." Es gibt also eine Menge Dinge, die von anderen Sprachen zur Verfügung gestellt werden, für die Schema lediglich Bausteine ​​bereitstellt. Jede gegebene Scheme-Implementierung kann eine vollständigere Bibliothek bereitstellen, und die SRFIs http://srfi.schemers.org/ helfen, einige der Erweiterungen der Kernsprache zu standardisieren. –

+0

Okay, danke –

7

Wenn Sie bitweises xor von zwei Ganzzahlen meinen, dann hat jedes Schema seinen eigenen Namen (falls vorhanden), da es in keinem Standard ist. Zum Beispiel hat PLT these bitwise functions, einschließlich bitwise-xor.

(Uh, wenn Sie über booleans sprechen, dann ja, not & or sind es ...)

7

geben kann. Soweit ich aus der R6RS (die neueste Definition des Schemas) sagen kann, gibt es keine vordefinierte Exklusiv-oder Operation. Allerdings entspricht xornot equals für boolesche Werte, so dass es sehr einfach ist, selbst zu definieren, wenn es keine eingebaute Funktion dafür gibt.

die Argumente Unter der Annahme, werden auf die Regelung booleans beschränkt Werte #f und #t,

(define (xor a b) 
    (not (boolean=? a b))) 

den Job tun.

5

Art eine andere Art der Antwort:

(define xor 
    (lambda (a b) 
    (cond 
     (a (not b)) 
     (else b)))) 
0

Da xor mit einer beliebigen Anzahl von Argumenten verwendet werden könnte, ist die einzige Voraussetzung, dass die Anzahl der wahren Begebenheiten ungerade sein. Es könnte etwa auf diese Weise definiert werden:

(define (true? x) (eqv? x #t)) 

(define (xor . args) 
    (odd? (length (filter true? args)))) 

Kein Argument Prüfung muss getan werden, da eine beliebige Anzahl von Argumenten (einschließlich keine) die richtige Antwort wird zurückkehren.

Diese einfache Implementierung hat jedoch Effizienzprobleme: Länge und Filter durchlaufen die Liste zweimal; also dachte ich, ich könnte beides und auch die andere nutzlose Prädikatenprozedur "wahr?" entfernen.

Der Wert ungerade? receive ist der Wert des Akkumulators (aka ac), wenn args keine verbleibenden wahr auswertenden Mitglieder hat. Wenn echte Evaluierungselemente existieren, wiederhole mit acc + 1 und der Rest der Argumente beginnt mit dem nächsten wahren Wert oder evaluiert mit false, was bewirkt, dass acc mit der letzten Zählung zurückgegeben wird.

(define (xor . args) 
    (odd? (let count ([args (memv #t args)] 
        [acc 0]) 
      (if args 
       (count (memv #t (cdr args)) 
        (+ acc 1)) 
           acc)))) 
2

Lesen SRFI-1 warf ein neues Licht auf meine Antwort. Vergessen Sie Effizienz- und Einfachheitsprobleme oder sogar Tests! Diese Schönheit macht alles:

(define (xor . args) 
    (odd? (count (lambda (x) (eqv? x #t)) args))) 

Oder wenn Sie bevorzugen:

(define (true? x) (eqv? x #t)) 
(define (xor . args) (odd? (count true? args))) 
0
> (define (xor a b)(not (equal? (and a #t)(and b #t)))) 
> (xor 'hello 'world) 
$9 = #f 
> (xor #f #f) 
$10 = #f 
> (xor (> 1 100)(< 1 100)) 
$11 = #t 
0
(define (xor a b) 
    (and 
    (not (and a b)) 
    (or a b))) 
0

ich meinen Code vor kurzem überarbeitet, weil ich ‚xor in Schema benötigt und fand heraus, es war nicht gut genug...

Erstens, meine frühere Definition von "wahr? machte die Annahme, dass Argumente unter einer booleschen Operation getestet wurden. So ändern I:

(define (true? x) (eqv? #t)) 

... für:

(define (true? x) (not (eqv? x #f))) 

..., die mehr wie die "wahre" Definition von ‚wahr ist? Wie auch immer, da 'xor' #t zurückgibt, wenn seine Argumente 'ungerade' haben? Anzahl der "wahren" Argumente ist das Testen auf eine gerade Anzahl falscher Fälle äquivalent. Also hier ist meine überarbeitete 'xor:

(define (xor . args) 
    (even? (count (lambda (x) (eqv? x #f)) args))) 
+0

Nun, so (sogar? (Count (lambda (x) (eqv? X #f)) '(#t #t #t #f #f)) würde wahr und (sogar? (Count (Lambda (x) (eqv? x #f)) '(#t #t #t #f #f #f)) würde falsch zurückgeben, obwohl beide eine ungerade Anzahl von wahren Werten haben ... Warum sollte es gleichwertig sein? – marzipankaiser