1

3 つのブール値 A、B、C があります。これらの値のいずれかが True でない場合にのみ実行される IF ステートメントを記述する必要があります。つまり、真理値表は次のようになります。

 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

これを書く最良の方法は何ですか?すべての可能性を列挙できることはわかっていますが、それは... 冗長すぎるようです。:P

追加:アイデアが 1 つだけありました:

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

これにより、2 つの値が設定されていないことが確認されます。合計についての提案もOKです。さらに読みやすいかもしれません...

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

PS これは製品コード用なので、パフォーマンスよりもコードの読みやすさを重視しています。

追加 2:既に回答が受け入れられていますが、好奇心旺盛な人のために - それは C# です。:) ただし、質問はほとんど言語に依存しません。

4

11 に答える 11

11

それらを整数の 1 と 0 として扱い、それらの合計が 1 に等しいことを確認するのはどうですか?

編集

それがc#.netであることがわかったので、最も読みやすいソリューションは次のようになると思います

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

上記は、クラス ライブラリ (appcode?) に隠されています。ここでは、表示する必要はありませんが、簡単にアクセスできます (たとえば、r# で ctrl + クリック)。実装は次のようになります。

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

...

bool check = noMoreThanOne(true, true, false, any, amount, of, bools);
于 2009-07-08T11:35:39.123 に答える
9

Karnaugh マップに慣れる必要があります。コンセプトはエレクトロニクスに最もよく適用されますが、ここでも非常に役立ちます。とても簡単です (ウィキペディアの説明は長く見えますが、徹底しています)。

于 2009-07-08T11:41:25.307 に答える
6

(A XOR B XOR C) OR NOT (A OR B OR C)

編集: Vilx が指摘したように、これは正しくありません。

A と B が両方とも 1 で、C が 0 の場合、A XOR B は 0 になり、全体の結果は 0 になります。

どうですか:(aとb)ではなく(aとc)ではなく、(bとc)ではありません

于 2009-07-08T11:37:37.420 に答える
3

ロジックを逆にすると、両方とも true のブール値のペアがある場合、条件を false にする必要があります。

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

完全に異なるものについては、ブール値を配列に入れて、真の値がいくつあるかを数えることができます。

if ((new bool[] { a, b, c }).Where(x => x).Count() <= 1) { ... }
于 2009-07-08T11:59:31.837 に答える
3

私は最大限の保守性と可読性を求めています。

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

static int NumThatAreTrue(params bool[] bools)
{
    return bools.Where(b => b).Count();
}
于 2009-07-08T12:07:05.957 に答える
2

ここにはたくさんの答えがありますが、私は別の答えを持っています!

a ^ b ^ c ^ (a == b && b == c)
于 2012-02-02T20:25:43.710 に答える
1

与えられた真理値表の最小ブール式を見つける一般的な方法は、カルノー マップを使用することです。

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

Web 上にはいくつかのオンライン最小化ツールがあります。ここにあるもの(記事からリンクされていますが、ドイツ語ですが)は次の表現を見つけます:

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

ただし、コードの読みやすさを重視する場合は、おそらく「sum<=1」という考えを採用するでしょう。すべての言語が false==0 および true==1 を保証するわけではないことに注意してください。ただし、独自のソリューションで処理したので、おそらくこれに気付いているでしょう。

于 2009-07-08T11:48:34.073 に答える
0

古き良きロジック:

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

ヒントを参考にして、必要に応じてさらに単純化してください。

そして、ええ、カルノーマップに慣れてください

于 2009-07-08T11:41:36.350 に答える
0

自分がやろうとしていることを簡単に理解できるものが欲しいのか、それともできるだけ論理的に単純なものが欲しいのかによって異なります。他の人が論理的に単純な回答を投稿しているので、何が起こっているのか (そして、さまざまな入力に対する結果がどうなるか) がより明確になるものを次に示します。

  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"
于 2009-07-08T11:48:52.310 に答える
0

私は加算ソリューションが好きですが、ビットフィールドでもそれを行うためのハックがあります.

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 */ }
于 2009-07-08T12:10:35.763 に答える
0

d のソリューションのコード デモンストレーション:

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

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

}
于 2009-07-08T12:15:43.933 に答える