Frage

Ich habe drei Boolesche Werte A, B und C. Ich brauche eine IF-Anweisung zu schreiben, wenn ausführen wird und nur dann, wenn nicht mehr als einer dieser Werte wahr ist. Mit anderen Worten, hier ist die Wahrheitstabelle:

 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ß, ich kann alle Möglichkeiten aufzählen, aber das scheint ... zu ausführlich. : P

am: Gerade hatte eine Idee:

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

Es wird geprüft, dass keine zwei Werte gesetzt. 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 die Produktion Code, also werde ich mehr für die Lesbarkeit des Codes als Leistung.

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

War es hilfreich?

Lösung

, wie etwa die Behandlung von ihnen als ganzer Zahl 1 und 0, und die Überprüfung, dass ihre Summe gleich 1?

Bearbeiten :

jetzt, da wir wissen, dass es c # .net ist, ich denke, die meisten lesbare Lösung wie

aussehen etwas würde
public static class Extensions
{
    public static int ToInt(this bool b)
    {
        return b ? 1 : 0;
    }
}

die oben versteckten in einer Klassenbibliothek (? AppCode), wo wir es nicht sehen müssen, doch kann es leicht zugänglich machen (ctrl + Klick in r #, zum Beispiel) und dann die Umsetzung einfach sein:

public bool noMoreThanOne(params bool[] bools) 
{ 
    return bools.ToList().Sum(b => b.ToInt()) <= 1; 
}

...

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

Andere Tipps

Sie shold machen Sie sich mit Karnaugh Karten . Konzept wird am häufigsten auf Elektronik angewandt, ist aber sehr auch hier nützlich. Es ist sehr einfach (dachte Wikipedia Erklärung lang sieht - es ist gründlich).

(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 wird 0

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

Wenn Sie die Logik umdrehen, möchten Sie die Bedingung falsch sein, wenn Sie jedes Paar von booleans haben, die beide erfüllt sind:

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 sind:

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

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

static bool ZeroOrOneAreTrue(params bool[] bools)
{
    return NumThatAreTrue(bools) <= 1;
}

static int NumThatAreTrue(params bool[] bools)
{
    return bools.Where(b => b).Count();
}

Es gibt viele Antworten hier, aber ich habe ein anderes!

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

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-Minimierer im Internet. Das man hier (im Zusammenhang mit dem Artikel, es ist in Deutsch, obwohl) findet den folgenden Ausdruck:

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

Wenn Sie die Lesbarkeit des Codes gehen, obwohl, würde ich wahrscheinlich mit der Idee der „Summe <= 1“ gehen. Achten Sie darauf, dass nicht alle Sprachen garantieren, dass falsche == 0 und wahr == 1 - aber du bist wahrscheinlich bewusst ist, da Sie kümmern sich um sie in Ihrer eigenen Lösung genommen haben.

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))

Nehmen Sie den Hinweis und weiter vereinfachen, wenn Sie wollen.

Und ja, erhalten Sie sich selbst vertraut mit Karnaugh Karten

davon ab, ob Sie etwas wollen, wo es ist leicht zu verstehen, was Sie zu tun versuchen, oder etwas, das als logisch einfach ist, wie sein kann. 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 wird):

  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"

Ich mag die Additionslösung, aber hier ist ein Hack zu tun, dass mit Bitfeldern auch.

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 */ }

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

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top