質問
私は、これらの値の1つ以下がTrueでない場合にのみ実行されるIF文を記述する必要が3つのブール値A、BおよびCを持っています。言い換えれば、ここでの真理値表は次のとおりです。
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アイデアます:
!(&& B)&&!(B && C)&&!(&& C)
これには二つの値が設定されていないことをチェックします。合計についての提案にもOKです。さらに読みやすいかもしれない...
(A 1:0)+(B 1:0)+(C?1:0)<= 1
P.S。これは、生産コード用ですので、私はより多くのコードの可読性のための性能よりつもりです。
をすでに受け入れ答えが、好奇心旺盛なもののために - それは、C#です。の 2を追加しました。 :)ご質問は、しかしかなり多くの言語に依存しないです。
解決
どのように整数1と0として扱うと、その合計は1に等しいことを確認するでしょうか?
編集
今、我々は、それは、C#.NETのだということを知っていることを、私は最も読みやすいソリューションが多少
のように見えると思いますpublic static class Extensions
{
public static int ToInt(this bool b)
{
return b ? 1 : 0;
}
}
<:クラスライブラリ(?appcode)私たちはそれを見ていない、まだ簡単にアクセスすることができます(CTRL +例えば、R#でクリック)して、実装は簡単になります上記の隠れ/ P>
public bool noMoreThanOne(params bool[] bools)
{
return bools.ToList().Sum(b => b.ToInt()) <= 1;
}
...
bool check = noMoreThanOne(true, true, false, any, amount, of, bools);
他のヒント
あなたは慣れるSHOLD。コンセプトは、ほとんどの場合、電子機器に適用されるが、ここにも非常に有用です。それは(Wikipediaの説明が長く見えるんと思った - それは徹底します)は非常に簡単です。
(XOR B XOR C)OR NOT(A OR B OR C)
編集:Vilxで指摘したように、これは権利ではありません。
。A及びBが両方とも1であり、Cが0の場合、XOR Bが0になる、全体的な結果は0になります。
どの程度: NOT(A AND B)AND NOT(A AND C)AND NOT(B AND C)
、あなたは真の両方であるブール値の任意のペアを持っている場合は、条件が偽になりたいます:
if (! ((a && b) || (a && c) || (b && c))) { ... }
全く別の何かのために、あなたは配列にブール値を入れてありますどのように多くの真の値数えることができます
if ((new bool[] { a, b, c }).Where(x => x).Count() <= 1) { ... }
私は最大の保守性と読みやすさのために行くと思います。
static bool ZeroOrOneAreTrue(params bool[] bools)
{
return NumThatAreTrue(bools) <= 1;
}
static int NumThatAreTrue(params bool[] bools)
{
return bools.Where(b => b).Count();
}
があり、多くの答えはここにあるが、私は別のものを持っている!
a ^ b ^ c ^ (a == b && b == c)
与えられた真理値表のための最小限の論理式を発見する一般的な方法は、カルノー図を使用することです。
http://babbage.cs.qc.edu/courses/Minimize/
ウェブ上のいくつかのオンラインminimizersがあります。 (記事からリンク、それはしかし、ドイツ語です)、ここで1は次の式を見つけます:
(!A &&!B)|| (!A &&!C)|| (!B &&!C)
あなたは、コードの可読性のために行っている場合は、、しかし、私はおそらく「合計<= 1」のアイデアを行くだろう。しかし、あなたがあなた自身の溶液中でそれの世話をしましたので、あなたは、おそらくこのことを認識している - ではないすべての言語は、その偽== 0と真== 1を保証するように注意してください。
グッド老いロジックます:
+ = 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))
ヒントを取り、あなたがしたい場合は、さらに簡素化します。
そして、ええ、カルノー図でおなじみのあなたの自己を取得
は、あなたがそれはあなたがやろうとしているかを理解するのは簡単です何か、または論理的に単純なものとして何かをしたいかどうかによって異なります。他の人々はので、ここでそれは何が起こっているのかをより明確だ1(とどのような結果が異なる入力のためになりますが)ですが、論理的に簡単な答えを投稿してます:
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"
私は、添加液を好きですが、ここでもビットフィールドでそれを行うためのハックです。
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 */ }
D'sのソリューションのコードのデモンストレーションます:
int total=0;
if (A) total++;
if (B) total++;
if (C) total++;
if (total<=1) // iff no more than one is true.
{
// execute
}