문제

나는 세 가지 부울 값 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

}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top