문제
나는 세 가지 부울 값 A, B 및 C를 가지고 있습니다.이 값 중 하나 이상이 사실이 아닌 경우에만 실행할 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
이것을 쓰는 가장 좋은 방법은 무엇입니까? 나는 모든 가능성을 열거 할 수 있다는 것을 알고 있지만, 그것은 너무 장황한 것 같습니다. :피
추가 : 그냥 한 가지 아이디어가있었습니다.
! (a && b) &&! (b && c) &&! (a && c)
이것은 두 값이 설정되지 않은지 확인합니다. 합계에 대한 제안도 괜찮습니다. 더 읽기 쉬운 ...
(a? 1 : 0) + (b? 1 : 0) + (c? 1 : 0) <= 1
추신 : 이것은 프로덕션 코드를위한 것이므로 성능보다 코드 가독성을 위해 더 많이 가고 있습니다.
추가 2 : 이미 받아 들여지는 대답이지만 호기심 많은 사람들에게는 C#입니다. :) 질문은 언어에 대한 정보가 거의 없습니다.
해결책
그것들을 정수 1과 0으로 취급하고 그들의 합이 1과 같은 것을 확인하는 것은 어떻습니까?
편집하다:
이제 우리는 그것이 C#.net이라는 것을 알았으므로 가장 읽기 쉬운 솔루션은 다소 좋아 보일 것입니다.
public static class Extensions
{
public static int ToInt(this bool b)
{
return b ? 1 : 0;
}
}
위의 내용은 클래스 라이브러리 (AppCode?)에 자리 잡고 있지만 볼 필요가 없지만 쉽게 액세스 할 수 있습니다 (예 : Ctrl+Click in R#). 구현은 다음과 같습니다.
public bool noMoreThanOne(params bool[] bools)
{
return bools.ToList().Sum(b => b.ToInt()) <= 1;
}
...
bool check = noMoreThanOne(true, true, false, any, amount, of, bools);
다른 팁
당신은 자신을 친숙하게 만듭니다 Karnaugh지도. 개념은 전자 제품에 가장 많이 적용되지만 여기에서도 매우 유용합니다. 매우 쉽습니다 (Wikipedia 설명이 오래 보입니다. 철저합니다).
(a xor b xor c) 여부 (a 또는 b 또는 c)
편집 : Vilx가 지적했듯이 이것은 옳지 않습니다.
A와 B가 모두 1이고 C가 0이면 XOR B는 0이면 전체 결과는 0이됩니다.
어떨까요?
논리를 돌리면 두 가지 부울 한 쌍이 있으면 조건이 거짓이되기를 원합니다.
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)
주어진 진실 테이블에 대한 최소 부울 표현을 찾는 일반적인 방법은 Karnaugh지도를 사용하는 것입니다.
http://babbage.cs.qc.edu/courses/minimize/
웹에는 여러 온라인 최소화자가 있습니다. 여기에있는 것은 (기사에서 링크 된 독일어로 연결되어 있음) 다음과 같은 표현을 찾습니다.
(! a &&! b) || (! a &&! c) || (! b &&! c)
그러나 코드 가독성을 원한다면 아마도 "sum <= 1"이라는 아이디어를 가지고있을 것입니다. 모든 언어가 False == 0 및 true == 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))
원하는 경우 힌트를 가져 와서 더 단순화하십시오.
그리고 그래, Karnaugh지도에 익숙해 지도록
당신이하려는 일을 쉽게 이해하기 쉬운 곳, 또는 논리적으로 단순한 것만 큼 무언가를 원하는 곳을 원하는지 여부에 따라 달라집니다. 다른 사람들은 논리적으로 간단한 답변을 게시하고 있으므로 여기에 무슨 일이 일어나고 있는지 더 명확한 곳이 있습니다 (그리고 다른 입력에 대한 결과가 무엇인지) :
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의 솔루션의 코드 데모 :
int total=0;
if (A) total++;
if (B) total++;
if (C) total++;
if (total<=1) // iff no more than one is true.
{
// execute
}