Pregunta

tres valores booleanos

Tengo A, B y C. Tengo que escribir una instrucción IF que se ejecuta si y sólo si hay más de uno de estos valores es cierto. En otras palabras, aquí está la tabla de verdad:

 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

¿Cuál es la mejor manera de escribir esto? Sé que puedo enumerar todas las posibilidades, pero que parece ... demasiado prolijo. : P

Agregado: Sólo tenía una idea:

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

Esto comprueba que no hay dos valores se establecen. La sugerencia acerca de sumas está bien también. Incluso más legible tal vez ...

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

P.S. Esto es para el código de producción, así que voy más por la legibilidad del código de rendimiento.

Agregado 2: respuesta ya aceptado, pero para los curiosos - es C #. :) La pregunta es más o menos independiente del idioma, aunque.

¿Fue útil?

Solución

¿Qué hay de tratarlos como número entero 1 y 0, y la comprobación de que su suma es igual a 1?

Editar

Ahora que sabemos que es C # .NET, creo que la solución más legible se vería algo así como

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

lo anterior escondido en una biblioteca de clases (? AppCode) en el que no hay que verlo, sin embargo, puede fácilmente acceder a él (Ctrl + clic en r #, por ejemplo) y luego la puesta en práctica serán simplemente:

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

...

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

Otros consejos

shold familiarice con Karnaugh mapas . Concepto se aplica más frecuentemente a la electrónica, pero es muy útil aquí también. Es muy fácil (pensó Wikipedia explicación se parece mucho - es exhaustiva).

(A XOR B XOR C) o no (A o B o C)

Editar:. Como ha señalado Vilx, esto no está bien

Si A y B son ambos 1, y C es 0, A XOR B será 0, el resultado global será 0.

¿Qué hay de: NO (A y B) y no (A y C) y NOT (B y C)

Si se activa la lógica alrededor, desea que la condición es falsa si tiene cualquier par de booleanos que son verdad:

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

Para algo completamente diferente, usted puede poner los valores booleanos en una matriz y contar el número de valores de verdad que son:

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

Me gustaría ir para una máxima facilidad de mantenimiento y facilidad de lectura.

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

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

Hay muchas respuestas aquí, pero no tengo otra!

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

Una forma general de la búsqueda de una expresión booleana mínimo para una tabla de verdad dada es usar un mapa de Karnaugh:

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

Hay varias minimizers en línea en la web. El uno aquí (vinculado a la del artículo, es en alemán, aunque) encuentra la siguiente expresión:

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

Si usted va para la legibilidad del código, sin embargo, probablemente me iría con la idea de "suma <= 1". Tener cuidado de que no todos los idiomas garantizan que la falsa y la verdadera == 0 == 1 - pero usted es probablemente consciente de esto, ya se ha encargado de ella en su propia solución.

El bueno de lógica':

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

Tome la indirecta y simplificar aún más si lo desea.

Y sí, obtener su auto familiarizado con Karnaugh mapas

depende de si quieres algo, donde es fácil de entender lo que estás tratando de hacer, o algo que es tan lógicamente simple como puede ser. Otras personas están publicando respuestas lógicamente simples, así que aquí está uno donde es más claro lo que está pasando (y lo que será el resultado de diferentes entradas):

  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"

Me gusta la solución de adición, pero aquí hay un truco para hacer eso con campos de bits también.

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

manifestaciones Código de la solución de 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

}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top