2010-10-31 5 views
1


J'ai un programme java où je veux valider si l'un des 3 booléens est faux. Je veux comprendre la plus petite expression que je puisse écrire pour vérifier les permutations.Nombre minimum de contrôles pour valider une table de vérité

if(!(needsWork && (needsApproval || isAdmin)))

Je pense que cela est suffisant pour faire en sorte que si l'un des 3 booléens est faux, je veux arrêter le traitement. Cependant, j'ai la suspicion furtive que je manque quelque chose.

+0

Umm ... si needsWork et needsApproval sont vraies, la valeur de isAdmin n'a pas d'importance dans votre mise en œuvre. Était-ce par but? – thejh

+0

Voilà comment je l'ai actuellement, je demandais quel est le moyen le plus court pour évaluer la table de vérité est – Woot4Moo

Répondre

7

Est-ce que if (!needsWork || !needsApproval || !isAdmin) ne fonctionnerait pas? Java prend en charge l'évaluation de court-circuit.

+0

J'allais pour plus lisible, c'est pourquoi je mets le! outside a parens – Woot4Moo

+2

Assez juste. Dans ce cas 'if (! (NeedsWork && needsApproval && isAdmin))' est probablement aussi succinct que possible. –

+0

merci que ce que je cherchais – Woot4Moo

2
if(!(needsWork & needsApproval & isAdmin)) 
+0

Pas tout à fait, voir l'OP. Je suis d'accord sur l'utilisation d'opérateurs bitwise ici plutôt que les opérateurs McCarthy. – EJP

6

Depuis

`any 3 booleans are false` (i.e. `!a || !b || !c`) 

et

`(! (needsWork && (needsApproval || isAdmin))` (i.e. (! (a && (b || c))` 

ont différentes tables de vérité, êtes-vous sûr que les cas qui sont différents ne comptent pas?

a b c (!a || !b || !c) (! (a && (b || c))) 
T T T   F     F   
T T F   T     F 
T F T   T     F 
T F F   T     T 
F T T   T     T 
F T F   T     T 
F F T   T     T 
F F F   T     T 

transformations

je vais souvent jouer avec des expressions booléennes pour essayer de clarifier ou de les simplifier et j'utiliser ces transformations logiques pour me aider:

// You can push (distribute) `!` into parenthesis if you reverse the `||` or `&&` operator inside: 
! (a || b)    <=> (! a && ! b) 
! (a || b || c || ...) <=> (! a && ! b && ! c && ...) 

! (a && b)    <=> (! a || ! b) 
! (a && b && c && ...) <=> (! a || ! b || ! c || ...) 

// You can drop parens when the boolean operator outside the parens is the same as inside: 
(a || (b || c || ...)) <=> (a || b || c) 
(a && (b && c && ...)) <=> (a && b && c) 

// You can push (distribute) a boolean op into parenthesis by applying it to each term inside: 
(a || (b && c)   <=> ((a || b) && (a || c) 
(a || (b && c && ...) <=> ((a || b) && (a || c) && (a || ...) ... 

(a && (b || c)   <=> ((a && b) || (a && c)) 
(a && (b || c || ...) <=> ((a && b) || (a && c) || (a || ...) ... 

// XOR means the term values have to be different: 
(a^b)    <=> ((a && !b) || (!a && b)) 

// XOR means the same as OR unless both terms are true: 
(a^b)    <=> ((a || b) && ! (a && b)) 

Il y a Bien sûr, beaucoup d'autres, mais ce sont ceux que j'utilise le plus souvent. Cela peut sembler compliqué, mais ils sont faciles à apprendre par cœur une fois que vous commencez à les pratiquer.

Dans votre cas, si vous voulez voir ce que certaines déclarations équivalentes possibles pour:

(! (needsWork && (needsApproval || isAdmin))) 

voici quelques transformations:

(! (needsWork && (needsApproval || isAdmin))) => [push the '!' through the `()`] 
(! needsWork || ! (needsApproval || isAdmin)) => [push the 2nd '!' through the `()`] 
(! needsWork || (! needsApproval && ! isAdmin)) 

mais je ne vois pas de véritable simplification de ce tu as.

Bien sûr, si la vérification que le any of 3 booleans are false est très bien, vos choix sont simples

(! needsWork || ! needsApproval || ! isAdmin) => [or pull the `!` outside the `()`] 
(! (needsWork && needsApproval && isAdmin)) 
+1

Ceci est très complet. – Woot4Moo

+1

On dirait que les tables de vérité du livre How to Prove It de Daniel J. Velleman. – orangepips

+2

Ce sont les lois de Morgan. – EJP

Questions connexes