Asignación:
Traduzca las siguientes expresiones de lenguaje natural a expresiones C ++. Suponga que todas las variables son números no negativos o booleanos (de valor verdadero o falso).
Lenguaje natural:
O a y b son falsos o c es verdadero, pero no ambos.
Mi solución:
(a==0 && b==0)xor(c==1)
Solución de profesores:
(!a && !b) != c
Preguntas:
Creo que entiendo un poco el primer paréntesis, al decir "no-a" y "no-b" creo que a y b deben estar equivocados, siempre que se suponga que ab no es cero al principio. ¿Derecha?
Pero, ¿qué pasa con la parte que dice "desigual a c"?
No entiendo la solución de los profesores, ¿alguien puede analizarla por mí?
¡Gracias por la ayuda!
a == b or c
lugar dea == b or a ==c
. El problema es que lanuage hablado es imprecisa y, de hecho ambas interpretaciones podría ser válidoRespuestas:
Asumiré eso
a
,b
y loc
sonbool
.Dibujemos algunas tablas de verdad:
Como se puede ver,
a
ya==1
son equivalentes, y!a
ya==0
también son equivalentes, por lo que se puede reescribir(a==0 && b==0)xor(c==1)
como(!a && !b) xor c
.Ahora algunas tablas de verdad más:
Entonces
a!=b
es equivalente aa xor b
, entonces podemos reescribir(!a && !b) xor c
en(!a && !b)!=c
. Como puede ver, sus soluciones son totalmente equivalentes, solo escritas con diferentes 'signos'.UPD : Olvidé mencionarlo. Hay razones por las que la solución del profesor se ve exactamente de esa manera.
La solución del profesor es más idiomática. Si bien su solución es técnicamente correcta, no es un código idiomático de C ++.
El primer pequeño problema es el uso de tipos. Su solución se basa en la conversión entre
int
ybool
cuando compara el valor booleano con un número o usoxor
, que es un operador 'exclusivo a nivel de bit' o 'que también actúa sobreint
s. En un C ++ moderno, es mucho más apreciado usar valores de tipos correctos y no confiar en tales conversiones, ya que a veces no son tan claras y difíciles de razonar. Parabool
tales valores sontrue
y enfalse
lugar de1
y0
respectivamente. También!=
es más apropiado quexor
porque, aunque técnicamentebool
s se almacenan como números, pero, desde el punto de vista semicográfico, no tiene ningún número, solo valores lógicos.El segundo problema también se refiere a la idioma. Se encuentra aquí:
a == 0
. No se considera una buena práctica comparar expresiones booleanas con constantes booleanas. Como ya sabes,a == true
es totalmente equivalente a justoa
, ya == false
es justo!a
onot a
(prefiero lo último). Para comprender la razón por la cual esa comparación no es buena, solo compare dos fragmentos de código y decida, lo cual es más claro:vs
fuente
Piensa en booleanos, no en pedacitos
En resumen, la solución de tu profesor es mejor (pero sigue siendo incorrecta, estrictamente hablando, ver más abajo) porque usa operadores booleanos en lugar de operadores bit a bit y trata los booleanos como enteros. La expresión
c==1
para representar "c es verdadero" es incorrecta porque si c puede ser un número (de acuerdo con la asignación establecida), cualquier valor distinto de cero de c se considerará como representativotrue
.Vea esta pregunta sobre por qué es mejor no comparar booleanos con 0 o 1, incluso cuando es seguro hacerlo.
Una muy buena razón para no usar
xor
es que esta es la operación u exclusiva exclusiva en bits . Resulta que funciona en su ejemplo porque tanto el lado izquierdo como el derecho son expresiones booleanas que se convierten a 1 o 0 (ver de nuevo 1 ).El booleano exclusivo-o es de hecho
!=
.Desglosando la expresión
Para comprender mejor la solución de su profesor, es más fácil reemplazar los operadores booleanos con sus equivalentes de "token alternativo", lo que lo convierte en un código C ++ mejor redable (imho) y completamente equivalente: ¡usando 'not' for '!' y 'y' para '&&' obtienes
Desafortunadamente, no hay
exclusive_or
otro operador lógiconot_eq
que no sea útil en este caso.Si desglosamos la expresión del lenguaje natural:
primero en una oración sobre proposiciones booleanas A y B:
esto se traduce en
A != B
(solo para booleanos, no para ningún tipo A y B).Entonces la proposición A era
que se puede indicar como
que se traduce
(not a and not b)
y finalmenteLo que simplemente se traduce en
c
. Combinándolos obtienes de nuevo(not a and not b) != c
.Para una explicación más detallada de cómo funciona esta expresión, me remito a las tablas de verdad que otros han dado en sus respuestas.
Ambos están equivocados
Y si puedo señalar: la asignación original declaró que a, byc pueden ser números no negativos, pero no indicó inequívocamente que si fueran números, deberían limitarse a los valores 0 y 1. Si hay algún número que sea no 0 representa
true
, como es habitual, entonces el siguiente código arrojaría una respuesta sorprendente :fuente
a
,b
yc
se declaran comobool
, en cuyo casoc == 1
es correcto , aunque es un código atroz. De todos modos, esta es la respuesta que habría escrito: el código de OP puede ser equivalente al del profesor, pero es malo C ++.variables are non-negative numbers or boolean
. Entonces haga un +1 a @dhavenith de mi parte por captar un detalle que la mayoría de los demás se perdieron (incluido yo, inicialmente).Trataré de explicar con algunas palabras más: los números se pueden convertir implícitamente en valores booleanos:
Fuente en cppreference
Esto lleva a las siguientes conclusiones:
a == 0
es lo mismo que!a
, porquea
se convierte en un booleano y luego se invierte, lo que es igual!(a != 0)
. Lo mismo vale para b.c==1
solo será cierto cuando seac
igual a 1. El uso de la conversión(bool)c
produciríatrue
cuandoc != 0
no solo sic == 1
. Por lo tanto, puede funcionar, porque generalmente se usa el valor 1 para representartrue
, pero no está garantizado.a != b
es lo mismo quea xor b
cuandoa
yb
ar expresiones booleanas. Es cierto, cuando un valor u otro es cierto, pero no ambos. En este caso, el lado izquierdo(a==0 && b==0)
es booleano, por lo que el lado derecho tambiénc
se convierte en booleano, por lo tanto, ambos lados se interpretan como expresiones booleanas, por lo tanto,!=
es el mismo quexor
en este caso.Puede verificar todo esto usted mismo con las tablas de verdad que proporcionan las otras respuestas.
fuente
Como podemos ver en las tablas de verdad:
!
(not
) y==0
dar los mismos resultados.!=
yxor
dar los mismos resultados.c==1
es lo mismo que soloc
Entonces, uno debajo del otro, muestra por qué estas 2 expresiones dan el mismo resultado:
Tablas de verdad:
No
== 0
== 1
Y
No es igual
XOR
fuente