Tugas:
Terjemahkan ekspresi bahasa alami berikut ke ekspresi C ++. Asumsikan bahwa semua variabel adalah angka non-negatif atau boolean (bernilai benar atau salah).
Bahasa alami:
Baik a dan b keduanya salah atau c benar, tetapi tidak keduanya.
Solusi saya:
(a==0 && b==0)xor(c==1)
Solusi profesor:
(!a && !b) != c
Pertanyaan:
Saya pikir saya sedikit memahami tanda kurung pertama, dengan mengatakan "tidak-a" dan "tidak-b" Saya pikir bahwa a dan b harus salah, asalkan ab diasumsikan tidak nol pada awalnya. Baik?
Tetapi bagaimana dengan bagian yang mengatakan "tidak sama dengan c"?
Saya tidak mengerti solusi Profesor, adakah yang bisa memecahnya untuk saya?
Terima kasih atas bantuannya!
a == b or c
bukana == b or a ==c
. Masalahnya adalah bahwa bahasa yang diucapkan tidak tepat dan sebenarnya kedua interpretasi tersebut dapat validJawaban:
Saya akan menganggap itu
a
,b
danc
sekarangbool
.Mari kita menggambar beberapa tabel kebenaran:
Seperti yang Anda lihat,
a
dana==1
setara, dan!a
dana==0
juga setara, jadi kami dapat menulis ulang(a==0 && b==0)xor(c==1)
sebagai(!a && !b) xor c
.Sekarang beberapa tabel kebenaran:
Jadi
a!=b
setara dengana xor b
, sehingga kita dapat menulis ulang(!a && !b) xor c
untuk(!a && !b)!=c
. Seperti yang Anda lihat, solusi Anda sepenuhnya setara, hanya ditulis dengan 'tanda' yang berbeda.UPD : Lupa menyebutkan. Ada alasan mengapa solusi profesor terlihat persis seperti itu.
Solusi profesor lebih idiomatis. Meskipun solusi Anda secara teknis benar, itu bukan kode C ++ idiomatik.
Masalah kecil pertama adalah penggunaan tipe. Solusi Anda bergantung pada konversi antara
int
danbool
ketika Anda membandingkan nilai boolean dengan angka atau penggunaanxor
, yang juga merupakan operator 'bit-wise eksklusif atau' yang bekerja padaint
s juga. Dalam C ++ modern jauh lebih dihargai untuk menggunakan nilai-nilai dari jenis yang benar dan tidak bergantung pada konversi seperti itu karena mereka kadang-kadang tidak begitu jelas dan sulit untuk dipikirkan. Untukbool
nilai-nilai tersebuttrue
danfalse
bukannya masing1
-0
masing. Juga!=
lebih tepat daripadaxor
karena sementara secara teknisbool
disimpan sebagai angka, tetapi secara semantik Anda tidak memiliki angka, hanya nilai logis.Masalah kedua adalah tentang idiomasi juga. Ini terletak di sini:
a == 0
. Tidak dianggap praktik yang baik untuk membandingkan ekspresi boolean dengan konstanta boolean. Seperti yang sudah Anda ketahui,a == true
sepenuhnya setara dengan adila
, dana == false
adil!a
ataunot a
(saya lebih suka yang terakhir). Untuk memahami alasan mengapa pembandingan itu tidak baik, bandingkan saja dua cuplikan kode dan putuskan, yang lebih jelas:vs.
sumber
Pikirkan booleans, bukan bit
Singkatnya, solusi profesor Anda lebih baik (tetapi masih salah, secara tegas, lihat lebih jauh ke bawah) karena menggunakan operator boolean, bukan operator bitwise dan memperlakukan boolean sebagai bilangan bulat. Ungkapan
c==1
untuk mewakili "c benar" salah karena jika c dapat berupa angka (sesuai dengan penugasan yang dinyatakan) maka nilai bukan-nol dari c dianggap dianggap mewakilitrue
.Lihat pertanyaan ini tentang mengapa lebih baik tidak membandingkan boolean dengan 0 atau 1, bahkan ketika itu aman untuk dilakukan.
Satu alasan yang sangat bagus untuk tidak digunakan
xor
adalah karena ini adalah operasi atau bit-wise . Ini terjadi pada contoh Anda karena sisi kiri dan kanan adalah ekspresi boolean yang dikonversi menjadi 1 atau 0 (lihat lagi 1 ).Boolean eksklusif-atau sebenarnya
!=
.Memecah ekspresi
Untuk memahami solusi profesor Anda dengan lebih baik, lebih mudah untuk mengganti operator boolean dengan padanan "alternatif token" mereka, yang mengubahnya menjadi lebih baik dapat dirubah (imho) dan kode C ++ yang sepenuhnya setara: Menggunakan 'bukan' untuk '!' dan 'dan' untuk '&&' Anda dapatkan
Sayangnya, tidak ada
exclusive_or
operator logis selainnot_eq
, yang tidak membantu dalam kasus ini.Jika kita memecah ekspresi bahasa alami:
pertama menjadi kalimat tentang proposisi boolean A dan B:
ini diterjemahkan menjadi
A != B
(hanya untuk boolean, bukan untuk tipe A dan B).Kemudian proposisi A adalah
yang dapat dinyatakan sebagai
yang diterjemahkan menjadi
(not a and not b)
, dan akhirnyaYang diterjemahkan menjadi
c
. Menggabungkan mereka, Anda dapatkan lagi(not a and not b) != c
.Untuk penjelasan lebih lanjut bagaimana ungkapan ini kemudian bekerja, saya tunduk pada tabel kebenaran yang telah diberikan orang lain dalam jawaban mereka.
Anda berdua salah
Dan jika saya dapat melakukan nitpick: Tugas asli menyatakan bahwa a, b dan c dapat berupa angka-angka yang tidak negatif, tetapi tidak secara jelas menyatakan bahwa jika itu adalah angka, angka-angka tersebut harus dibatasi dengan nilai 0 dan 1. Jika ada angka yang bukan 0 mewakili
true
, seperti kebiasaan, maka kode berikut akan menghasilkan jawaban yang mengejutkan :sumber
a
,b
danc
dinyatakan sebagaibool
, dalam halc == 1
ini kode yang benar , meskipun mengerikan. Bagaimanapun, ini adalah jawaban yang akan saya tulis: Kode OP mungkin setara dengan profesor, tapi itu buruk C ++.variables are non-negative numbers or boolean
. Jadi +1 ke @dhavenith dari saya karena menangkap detail yang kebanyakan orang lain lewatkan (termasuk saya, awalnya).Saya akan mencoba menjelaskan dengan beberapa kata lagi: Angka dapat secara implisit dikonversi menjadi nilai boolean:
Sumber di cppreference
Ini mengarah pada kesimpulan berikut:
a == 0
sama dengan!a
, karenaa
dikonversi ke boolean dan kemudian dibalik, yang sama dengan!(a != 0)
. Hal yang sama berlaku untuk b.c==1
hanya akan menjadi benar ketikac
sama dengan 1. Menggunakan konversi(bool)c
akan menghasilkantrue
bilac != 0
tidak hanya jikac == 1
. Jadi itu bisa berhasil, karena orang biasanya menggunakan nilai 1 untuk mewakilitrue
, tetapi tidak garantued.a != b
sama dengana xor b
kapana
danb
ekspresi boolean. Itu benar, ketika satu nilai atau yang lain benar, tetapi tidak keduanya. Dalam hal ini sisi kiri(a==0 && b==0)
adalah boolean, sehingga sisi kananc
dikonversi menjadi boolean juga, dengan demikian, kedua belah pihak ditafsirkan sebagai ekspresi boolean, dengan demikian!=
sama sepertixor
dalam kasus ini.Anda dapat memeriksa sendiri semua ini dengan tabel kebenaran yang disediakan oleh jawaban lain.
sumber
Seperti yang bisa kita lihat dari tabel kebenaran:
!
(not
) dan==0
berikan hasil yang sama.!=
danxor
memberikan hasil yang sama.c==1
sama dengan adilc
Jadi satu di bawah yang lain, menunjukkan mengapa 2 ekspresi ini memberikan hasil yang sama:
Tabel kebenaran:
Tidak
== 0
== 1
Dan
Tidak sama
XOR
sumber