Affectation:
Traduisez les expressions de langage naturel suivantes en expressions C ++. Supposons que toutes les variables sont des nombres non négatifs ou booléens (de valeur true ou false).
Langage naturel:
Soit a et b sont faux ou c est vrai, mais pas les deux.
Ma solution:
(a==0 && b==0)xor(c==1)
Solution professeurs:
(!a && !b) != c
Des questions:
Je pense que je comprends un peu la première tranche, en disant "pas-a" et "pas-b" je pense que a et b doivent alors être faux, à condition que ab soit supposé non nul au début. Droite?
Mais qu'en est-il de la partie qui dit "inégal à c"?
Je ne comprends pas la solution Professeurs, quelqu'un peut-il la décomposer pour moi?
Merci pour l'aide!
a == b or c
lieu dea == b or a ==c
. Le problème est que le langage parlé est imprécis et que les deux interprétations pourraient être validesRéponses:
Je suppose que
a
,b
etc
sontbool
.Tirons quelques tables de vérité:
Comme vous pouvez le voir,
a
eta==1
sont équivalents, et!a
eta==0
sont également équivalents, nous pouvons donc réécrire(a==0 && b==0)xor(c==1)
en(!a && !b) xor c
.Maintenant, quelques tables de vérité supplémentaires:
Donc ,
a!=b
est équivalent àa xor b
, donc on peut réécrire(!a && !b) xor c
à(!a && !b)!=c
. Comme vous le voyez, vos solutions sont entièrement équivalentes, juste écrites avec différents «signes».UPD : J'ai oublié de mentionner. Il y a des raisons pour lesquelles la solution du professeur ressemble exactement à cela.
La solution du professeur est plus idiomatique. Bien que votre solution soit techniquement correcte, ce n'est pas un code C ++ idiomatique.
Le premier petit problème est l'utilisation des types. Votre solution repose sur la conversion entre
int
etbool
lorsque vous comparez la valeur booléenne à un nombre ou à une utilisationxor
, qui est également un opérateur «exclusif au niveau du bit» ou agissant sur lesint
s. Dans un C ++ moderne, il est beaucoup plus apprécié d'utiliser des valeurs de types corrects et de ne pas se fier à de telles conversions car elles ne sont parfois pas aussi claires et difficiles à raisonner. Carbool
ces valeurs sonttrue
etfalse
au lieu de1
et0
respectivement. Est également!=
plus approprié quexor
parce que, techniquement, lesbool
s sont stockés sous forme de nombres, mais sémantiquement vous n'avez pas de nombres, juste des valeurs logiques.Le deuxième problème concerne également l'idiomatie. Il se trouve ici:
a == 0
. Il n'est pas considéré comme une bonne pratique de comparer des expressions booléennes à des constantes booléennes. Comme vous le savez déjà,a == true
est entièrement équivalent à justea
, eta == false
est juste!a
ounot a
(je préfère ce dernier). Pour comprendre la raison pour laquelle cette comparaison n'est pas bonne, il suffit de comparer deux extraits de code et de décider, ce qui est plus clair:contre
la source
Pensez aux booléens, pas aux morceaux
En résumé, la solution de votre professeur est meilleure (mais toujours fausse, à proprement parler, voir plus loin) car elle utilise des opérateurs booléens au lieu d'opérateurs au niveau du bit et traite les booléens comme des entiers. L'expression
c==1
pour représenter "c est vrai" est incorrecte car si c peut être un nombre (selon l'affectation indiquée), alors toute valeur non nulle de c doit être considérée comme représentativetrue
.Consultez cette question pour savoir pourquoi il est préférable de ne pas comparer les booléens à 0 ou 1, même lorsque cela est sûr.
Une très bonne raison de ne pas l'utiliser
xor
est qu'il s'agit de l' opération ou de l'exclusivité bit à bit . Il se trouve que cela fonctionne dans votre exemple, car le côté gauche et le côté droit sont des expressions booléennes qui se convertissent en 1 ou 0 (voir à nouveau 1 ).Le booléen exclusif ou est en fait
!=
.Décomposer l'expression
Pour mieux comprendre la solution de votre professeur, il est plus facile de remplacer les opérateurs booléens par leurs équivalents de "jeton alternatif", ce qui en fait un code C ++ mieux réductible (à mon humble avis) et complètement équivalent: en utilisant 'not' for '!' et 'et' pour '&&' vous obtenez
Malheureusement, il n'y a aucun
exclusive_or
opérateur logique autre quenot_eq
, ce qui n'est pas utile dans ce cas.Si nous décomposons l'expression du langage naturel:
d'abord dans une phrase sur les propositions booléennes A et B:
cela se traduit par
A != B
(uniquement pour les booléens, pas pour les types A et B).Alors la proposition A était
qui peut être déclaré comme
qui se traduit par
(not a and not b)
, et enfinCe qui se traduit simplement par
c
. En les combinant, vous obtenez à nouveau(not a and not b) != c
.Pour plus d'explications sur le fonctionnement de cette expression, je m'en remets aux tables de vérité que d'autres ont données dans leurs réponses.
Vous vous trompez tous les deux
Et si je peux me moquer de moi: l'affectation d'origine a déclaré que a, b et c peuvent être des nombres non négatifs, mais n'a pas déclaré sans ambiguïté que s'il s'agissait de nombres, ils devraient être limités aux valeurs 0 et 1. Si un nombre quelconque est pas 0 représente
true
, comme c'est la coutume, alors le code suivant donnerait une réponse surprenante :la source
a
, espérons-le ,b
etc
sont déclarés commebool
, dans ce cas , le codec == 1
est correct , mais atroce. Quoi qu'il en soit, c'est la réponse que j'aurais écrite: le code OP peut être équivalent au professeur, mais c'est du mauvais C ++.variables are non-negative numbers or boolean
. Donc +1 à @dhavenith de ma part pour avoir saisi un détail que la plupart des autres ici ont manqué (y compris moi, au départ).Je vais essayer d'expliquer avec quelques mots: les nombres peuvent être implicitement convertis en valeurs booléennes:
Source sur cppreference
Cela conduit aux conclusions suivantes:
a == 0
est identique à!a
, cara
est converti en booléen puis inversé, ce qui équivaut à!(a != 0)
. Il en va de même pour b.c==1
deviendra vrai que lorsquec
est égal à 1. À l' aide de la conversion(bool)c
produiraittrue
quandc != 0
non seulement sic == 1
. Cela peut donc fonctionner, car on utilise généralement la valeur 1 pour représentertrue
, mais ce n'est pas garanti.a != b
est identique àa xor b
whena
et àb
des expressions booléennes. C'est vrai, quand une valeur ou l'autre est vraie, mais pas les deux. Dans ce cas, le côté gauche(a==0 && b==0)
est booléen, donc le côté droitc
est également converti en booléen, ainsi, les deux côtés sont interprétés comme des expressions booléennes, c'est donc!=
la même chose quexor
dans ce cas.Vous pouvez vérifier tout cela vous-même avec les tables de vérité fournies par les autres réponses.
la source
Comme nous pouvons le voir sur les tables de vérité:
!
(not
) et==0
donnent les mêmes résultats.!=
etxor
donner les mêmes résultats.c==1
est le même que justec
Donc, l'une sous l'autre, montre pourquoi ces 2 expressions donnent le même résultat:
Tables de vérité:
ne pas
== 0
== 1
Et
Inégal
XOR
la source