Tarefa:
Traduza as seguintes expressões de linguagem natural para expressões C ++. Suponha que todas as variáveis sejam números não negativos ou booleanos (com valor verdadeiro ou falso).
Linguagem Natural:
A e b são ambos falsos ou c é verdadeiro, mas não ambos.
Minha solução:
(a==0 && b==0)xor(c==1)
Solução para professores:
(!a && !b) != c
Questões:
Acho que entendi um pouco o primeiro colchete, dizendo "não-a" e "não-b". Acho que aeb deve estar errado, desde que ab seja assumido como zero no começo. Direita?
Mas e a parte que diz "desigual para c"?
Não entendo a solução dos professores, alguém pode me explicar?
Obrigado pela ajuda!
a == b or c
vez dea == b or a ==c
. O problema é que lanuage falada é impreciso e, na verdade, ambas as interpretações poderiam ser válidoRespostas:
Eu vou assumir isso
a
,b
ec
sãobool
.Vamos desenhar algumas tabelas da verdade:
Como você pode ver,
a
ea==1
são equivalentes, e!a
ea==0
também são equivalentes, de modo que podemos reescrever(a==0 && b==0)xor(c==1)
como(!a && !b) xor c
.Agora, mais algumas tabelas de verdade:
Então,
a!=b
é equivalente aa xor b
, para que possamos reescrever(!a && !b) xor c
para(!a && !b)!=c
. Como você vê, suas soluções são totalmente equivalentes, apenas escritas com diferentes 'sinais'.UPD : Esqueci de mencionar. Existem razões pelas quais a solução do professor parece exatamente dessa maneira.
A solução do professor é mais idiomática. Embora sua solução esteja tecnicamente correta, não é um código C ++ idiomático.
O primeiro pequeno problema é o uso de tipos. Sua solução depende da conversão entre
int
ebool
quando você compara o valor booleano com um número ou usoxor
, que é um operador 'bit-wise exclusive ou' atuando sobreint
s também. Em um C ++ moderno, é muito mais apreciado usar valores dos tipos corretos e não confiar nessas conversões, pois às vezes elas não são tão claras e difíceis de raciocinar. Parabool
tais valores sãotrue
e emfalse
vez de1
e0
respectivamente. Também!=
é mais apropriado do quexor
porque, enquanto tecnicamente,bool
s são armazenados como números, mas sematicamente você não possui números, apenas valores lógicos.A segunda questão também é sobre a idiomia. Encontra-se aqui:
a == 0
. Não é considerado uma boa prática comparar expressões booleanas com constantes booleanas. Como você já sabe,a == true
é totalmente equivalente a apenasa
, ea == false
é apenas!a
ounot a
(eu prefiro o último). Para entender o motivo pelo qual essa comparação não é boa, basta comparar dois trechos de código e decidir, o que é mais claro:vs
fonte
Pense booleanos, não bits
Em resumo, a solução do professor é melhor (mas ainda está errada, a rigor, veja mais adiante) porque ela usa operadores booleanos em vez de operadores bit a bit e trata os booleanos como números inteiros. A expressão
c==1
para representar "c é verdadeira" está incorreta porque se c pode ser um número (de acordo com a atribuição declarada), qualquer valor diferente de zero de c deve ser considerado como representandotrue
.Veja esta pergunta sobre por que é melhor não comparar booleanos com 0 ou 1, mesmo quando é seguro fazê-lo.
Uma boa razão para não usar
xor
é que esta é a operação ou exclusiva em termos de bits . Isso funciona no seu exemplo, porque o lado esquerdo e o lado direito são expressões booleanas que se convertem em 1 ou 0 (consulte novamente 1 ).O booleano exclusivo - ou é de fato
!=
.Quebrando a expressão
Para entender melhor a solução do professor, é mais fácil substituir os operadores booleanos por seus equivalentes "token alternativo", que o transformam em código C ++ melhor redable (imho) e completamente equivalente: Usando 'not' for '!' e 'e' para '&&' você obtém
Infelizmente, não há
exclusive_or
outro operador lógiconot_eq
que não seja útil nesse caso.Se quebrarmos a expressão da linguagem natural:
primeiro em uma frase sobre as proposições booleanas A e B:
isso se traduz em
A != B
(apenas para booleanos, não para qualquer tipo A e B).Então a proposição A foi
que pode ser indicado como
que se traduz em
(not a and not b)
, e finalmenteO que simplesmente se traduz em
c
. Combinando eles, você obtém novamente(not a and not b) != c
.Para mais explicações sobre como essa expressão funciona, eu refiro às tabelas da verdade que outros deram em suas respostas.
Vocês dois estão errados
E se eu puder nitpick: A atribuição original afirmou que a, bec podem ser números não negativos, mas não declarou inequivocamente que, se fossem números, deveriam ser limitados aos valores 0 e 1. Se houver um número que seja not 0 representa
true
, como é habitual, o código a seguir produziria uma resposta surpreendente :fonte
a
, esperançosamente ,b
ec
são declarados comobool
, nesse caso,c == 1
está correto , embora código atroz. Enfim, esta é a resposta que eu teria escrito: o código do OP pode ser equivalente ao do professor, mas é ruim em C ++.variables are non-negative numbers or boolean
. Então, marque +1 em @dhavenith por capturar um detalhe que a maioria das pessoas aqui perdeu (incluindo eu, inicialmente).Vou tentar explicar com mais algumas palavras: Os números podem ser implicitamente convertidos em valores booleanos:
Fonte sobre cppreference
Isso leva às seguintes conclusões:
a == 0
é o mesmo que!a
, porquea
é convertido em um booleano e depois invertido, o que é igual a!(a != 0)
. O mesmo vale para b.c==1
só será verdadeiro quando forc
igual a 1. O uso da conversão(bool)c
renderiatrue
quandoc != 0
não apenas sec == 1
. Portanto, pode funcionar, porque geralmente se usa o valor 1 para representartrue
, mas não é garantido.a != b
é o mesmo quea xor b
quandoa
eb
são expressões booleanas. É verdade, quando um valor ou outro é verdadeiro, mas não ambos. Nesse caso, o lado esquerdo(a==0 && b==0)
é booleano; portanto, o lado direito tambémc
é convertido em booleano; portanto, ambos os lados são interpretados como expressões booleanas; portanto,!=
é o mesmo quexor
neste caso.Você pode verificar tudo isso sozinho com as tabelas da verdade fornecidas pelas outras respostas.
fonte
Como podemos ver nas tabelas da verdade:
!
(not
) e==0
dê os mesmos resultados.!=
exor
dê os mesmos resultados.c==1
é o mesmo que apenasc
Então, um sob o outro, mostra por que essas duas expressões dão o mesmo resultado:
Tabelas da verdade:
Não
== 0
== 1
E
Não igual
XOR
fonte