class Verite { /*************************************************************************** * Les fonctions e1() et e2() retournent l'évaluation des expressions * * de l'énoncé. * ***************************************************************************/ /* Première expression */ static boolean e1(boolean a, boolean b, boolean c) { return (!a && !b && c) || (!a && b && !c) || (a && !b && !c) || (a && !b && c) || (a && b && !c); } /* Deuxième expression */ static boolean e2(boolean a, boolean b, boolean c) { return (a && !b) || (b && !c) || (!b && c); } /*************************************************************************** * Les fonctions afficheLigne0() et afficheLigne() correspondent au * * code servant à l'affichage des lignes du tableau. Ce code est en * * effet le même pour les trois fonctions afficheTableX() qui suivent. * ***************************************************************************/ /* Affiche l'entête de la table de vérité */ static void afficheLigne0() { System.out.println("\t\t\t\t"); } /* Affiche une ligne de la table de vérité pour les valeurs de a, b et * c données (booléens). */ static void afficheLigne(boolean a, boolean b, boolean c) { System.out.println(a + "\t" + b + "\t" + c + "\t" + e1(a, b, c) + "\t" + e2(a, b, c));; } /*************************************************************************** * Les trois fonctions afficheTable1(), afficheTable2() et afficheTable3() * * affichent la même table de vérité. Ces fonctions diffèrent simplement * * par l'algorithme utilisé pour énumérer les valeurs. * ***************************************************************************/ static void afficheTable1() { /* On utilise ici trois boucles imbriquées pour parcourir l'ensemble des combinaisons possibles pour les valeurs des booleanéens a, b et c. On remarque qu'un boucle de la forme : boolean x = false; do { ... x = !x; } while (x); fera exactement deux itérations : la première avec la valeur false pour x, et la seconde avec la valeur true pour x. */ afficheLigne0(); boolean a = false; do { boolean b = false; do { boolean c = false; do { afficheLigne(a, b, c); c = !c; } while (c); b = !b; } while (b); a = !a; } while (a); } static void afficheTable2() { /* On utilise ici aussi trois boucles imbriquées pour parcourir l'ensemble des combinaisons possibles pour les valeurs de a, b et c. Pour simplifier l'écriture par rapport à la fonction afficheTable1(), on utilise des entiers en posant que 0 signifie false, et toute autre valeur signifie true. */ afficheLigne0(); for (int a = 0; a < 2; a++) for (int b = 0; b < 2; b++) for (int c = 0; c < 2; c++) afficheLigne(a != 0, b != 0, c != 0); } static void afficheTable3() { /* Ici, on utilise la notation binaire des nombres (base 2) et les manipulations de bits. On remarque qu'en faisant varier un compteur de 000 à 111 (en notation binaire), et en décidant les valeurs des booléens a, b et c de la manière suivante : a vaut vrai si le bit 2 du compteur vaut 1, faux sinon b vaut vrai si le bit 1 du compteur vaut 1, faux sinon c vaut vrai si le bit 0 du compteur vaut 1, faux sinon alors toutes les combinaisons possibles des valeurs de a, b et c sont parcourues. Rappel(?), les opérateurs binaires disponibles en Java sont les suivants : ~ [opérateur unaire] pour le complément à 1 : tous les bits sont inversés & pour le ET bit à bit | pour le OU bit à bit ^ pour le OU EXCLUSIF bit à bit << pour un décalage vers la gauche : (x << n) est égal à la valeur de x décalée de n bits vers la gauche >> et >>> pour un décalage vers la droite : (x >> n) est égal à la valeur de x décalée de n bits vers la droite (cf. manuel pour la différence entre les deux) Ainsi : 1 << 3 est égal à la valeur 1 décalée de 3 bits vers la gauche. C'est donc égal à 1000 en notation binaire, qui lui-même est égal à (111 + 1) en notation binaire. i & 4 est égal à 4 si le bit 2 de i vaut 1, et égal à 0 sinon i & 2 est égal à 2 si le bit 1 de i vaut 1, et égal à 0 sinon i & 1 est égal à 1 si le bit 0 de i vaut 1, et égal à 0 sinon Le code devient alors beaucoup plus concis : il n'y a besoin que d'une seule boucle. */ afficheLigne0(); for (int i = 0; i < (1 << 3); i++) afficheLigne((i & 4) != 0, (i & 2) != 0, (i & 1) != 0); } /*************************************************************************** * Le programme principal * ***************************************************************************/ public static void main(String[] args) { System.out.println("---| afficheTable1() |-----------------------"); afficheTable1(); System.out.println("---| afficheTable2() |-----------------------"); afficheTable2(); System.out.println("---| afficheTable3() |-----------------------"); afficheTable3(); } }