2009-07-08 22 views
1

Ich habe drei boolesche Werte A, B und C. Ich muss eine IF-Anweisung schreiben, die genau dann ausgeführt wird, wenn nicht mehr als einer dieser Werte True ist. Mit anderen Worten, hier ist die Wahrheitstabelle:Wie schreibe ich den folgenden booleschen Ausdruck?

A | B | C | Result 
---+---+---+-------- 
0 | 0 | 0 | 1 
0 | 0 | 1 | 1 
0 | 1 | 0 | 1 
0 | 1 | 1 | 0 
1 | 0 | 0 | 1 
1 | 0 | 1 | 0 
1 | 1 | 0 | 0 
1 | 1 | 1 | 0 

Was ist der beste Weg, dies zu schreiben? Ich weiß, dass ich alle Möglichkeiten aufzählen kann, aber das scheint ... zu ausführlich. : P

Hinzugefügt: hatte nur eine Idee +!

(A & & B) & & (B & & C) & & (A & & C)

Prüft dass keine zwei Werte gesetzt sind. Der Vorschlag über Summen ist auch OK. Noch mehr lesbar vielleicht ...

(A 1: 0) + (B 1: 0) + (? C 1: 0) < = 1

P. S. Dies ist für den Produktionscode, daher gehe ich mehr auf Code-Lesbarkeit als auf Leistung.

Hinzugefügt 2: Bereits akzeptierte Antwort, aber für die Neugierigen - es ist C#. :) Die Frage ist jedoch ziemlich sprachunabhängig.

Antwort

11

Wie behandelt man sie als Integer-1 und 0, und prüft, ob ihre Summe gleich 1 ist?

EDIT:

jetzt, wo wir wissen, dass es C# .net ist, ich denke, die meisten lesbar Lösung etwas aussehen würde wie

public static class Extensions 
{ 
    public static int ToInt(this bool b) 
    { 
     return b ? 1 : 0; 
    } 
} 

die oben in einer Klassenbibliothek (AppCode versteckt?) wo wir es nicht sehen müssen, aber leicht darauf zugreifen können (Strg + Klick in R #, zum Beispiel) und dann wird die Implementierung einfach sein:

...

bool check = noMoreThanOne(true, true, false, any, amount, of, bools); 
+7

Summe gleich 1 oder 0. – Vicky

+0

, dass die Summe auf 1 – Josh

+0

hoppla kleiner oder gleich ist, diese Bedingung verfehlt, ja =) –

6

(A XOR B XOR C) oder nicht (A oder B oder C)

Edit: Wie Vilx wies darauf hin, das ist nicht richtig.

Wenn A und B beide 1 sind, und C 0, A XOR B 0 sein, das Gesamtergebnis 0 sein wird

Wie wäre: NOT (A und B) und NICHT (A UND C) UND NICHT (B UND C)

+4

Ich glaube nicht, dass dies der Wahrheitstabelle oben entspricht .... –

+0

Bugger, du hast recht. Mein Fehler. – Vicky

+1

Dies ergibt den falschen Wert, wenn a, b und c alle wahr sind. –

9

Sie sollten sich mit Karnaugh maps vertraut machen. Das Konzept wird meistens auf die Elektronik angewendet, ist aber auch hier sehr nützlich. Es ist sehr einfach (dachte Wikipedia Erklärung sieht lange aus - es ist gründlich).

+0

Beat mich dazu. :) –

0

Good ol‘Logik:

+ = OR 
. = AND 

R = Abar.Bbar.Cbar + Abar.Bbar.C + Abar.B.Cbar + A.Bbar.Cbar 
    = Abar.Bbar.(Cbar + C) + Abar.B.Cbar + A.Bbar.Cbar 
    = Abar.Bbar + Abar.B.Cbar + A.Bbar.Cbar 
    = Abar.Bbar + CBar(A XOR B) 
    = NOT(A OR B) OR (NOT C AND (A XOR B)) 

den Hinweis nehmen und weiter vereinfachen, wenn Sie wollen.

Und ja, erhalten Sie sich selbst vertraut mit Karnaugh Karten

+0

Ich denke das Endergebnis ist hier unleserlich. Karnaugh Karten sind für die Optimierung von Schaltungen, nicht für das Schreiben von verständlichen booleschen Ausdrücken ... –

+0

Ja, ich denke, ich stimme zu. – Swanand

+0

Obwohl unleserlich ist perfekt persönlich, ich bin mit dem Entwerfen von Schaltungen aufgewachsen, so dass das Endergebnis hier wie "puts" Hallo Welt! "Für mich erscheint. – Swanand

1

Eine allgemeine Art und Weise einen minimalen boolean Ausdruck für eine gegebene Wahrheitstabelle zu finden, ist eine Karnaugh Karte zu verwenden:

http://babbage.cs.qc.edu/courses/Minimize/

Es gibt mehrere Online-Minimizer im Internet. Der eine hier (verlinkt mit dem Artikel, der auf Deutsch ist) findet jedoch folgenden Ausdruck:

(! A & &! B) || (! A & &! C) || (! B &! C)

Wenn Sie für die Lesbarkeit des Codes gehen, würde ich wahrscheinlich mit der Idee "Summe < = 1" gehen. Achten Sie darauf, dass nicht alle Sprachen den Wert false == 0 und true == 1 haben - aber Sie sind sich dessen wahrscheinlich bewusst, seit Sie sich in Ihrer eigenen Lösung darum gekümmert haben.

0

Hängt davon ab, ob Sie etwas wollen, wo Sie leicht verstehen, was Sie zu tun versuchen, oder etwas, das so einfach wie logisch ist. Andere Menschen sind Entsendung logisch einfache Antworten, also hier ist eine, wo es ist mehr klar, was los ist (und was das Ergebnis für die verschiedenen Eingänge sein):

def only1st(a, b, c): 
    return a and not b and not c 

    if only1st(a, b, c) or only1st(b, a, c) or only1st(c, a, b): 
    print "Yes" 
    else: 
    print "No" 
+0

Sie vergaßen die Fall, wo alle drei falsch sind :) –

+0

Entfernen Sie "a und" von only1st, so ist es "nur" im Sinne von "höchstens" anstatt im Sinne von "genau", und du bist fertig. –

3

Wenn Sie die Logik umdrehen, möchten Sie den Zustand sein false, wenn Sie jedes Paar booleans haben, dass beide wahr:

if (! ((a && b) || (a && c) || (b && c))) { ... } 

Für etwas ganz anderes, können Sie die Boolesche Werte in einem Array setzen können und zählen, wie viele wahre Werte gibt es:

if ((new bool[] { a, b, c }).Where(x => x).Count() <= 1) { ... } 
+0

Ugh. .. nun, das ist verkrustet! Ich würde für Originalität upvote obwohl!: D –

3

Ich würde für maximale Wartbarkeit und Lesbarkeit gehen.

0

Ich mag die Addition Lösung, aber hier ist ein Hack, um das mit Bit-Feldern zu tun.

inline bool OnlyOneBitSet(int x) 
{ 
    // removes the leftmost bit, if zero, there was only one set. 
    return x & (x-1) == 0; 
} 

// macro for int conversion 
#define BOOLASINT(x) ((x)?1:0) 

// turn bools a, b, c into the bit field cba 
int i = (BOOLASINT(a) << 0) | BOOLASINT(b) << 1 | BOOLASINT(c) << 2; 

if (OnlyOneBitSet(i)) { /* tada */ } 
0

-Code Demonstration von d's Lösung:

int total=0; 
if (A) total++; 
if (B) total++; 
if (C) total++; 

if (total<=1) // iff no more than one is true. 
{ 
    // execute 

} 
+0

Ich denke, ich hatte auch eine in meiner Frage ...: P –

2

Es gibt hier viele Antworten, aber ich habe eine andere!

a^b^c^(a == b && b == c) 
+0

Süß, ich mag es! :) Obwohl ziemlich unnahbar, also nicht für die Produktion Code, aber ich mag es immer noch :) –

Verwandte Themen