Doğal dilden C ++ ifadesine


9

Görev:

Aşağıdaki doğal dil ifadelerini C ++ ifadelerine çevirin. Tüm değişkenlerin negatif olmayan sayılar veya boolean (true veya false değerine) olduğunu varsayalım.

Doğal lisan:

A ve b'nin ikisi de yanlıştır veya c doğrudur, ancak ikisi de değildir.

Çözümüm:

(a==0 && b==0)xor(c==1)

Profesörler çözümü:

(!a && !b) != c

Sorular:

  1. Sanırım ilk parantezleri biraz anlıyorum. Sağ?

  2. Peki "c'ye eşit değil" yazan kısım ne olacak?

  3. Profesörler çözümünü anlamıyorum, kimse benim için çözebilir mi?

Yardım için teşekkürler!


genel olarak, sözlü dil boole ifadelerini koda çevirirken dikkatli olurum. Yaygın bir hata, "A eşittir B veya C" yi a == b or cyerine çevirmektir a == b or a ==c. Sorun, konuşulan
dilin kesin olmaması

Yanıtlar:


5

Bunu varsayıyoruz a, bve cvardır bool.

Bazı doğruluk tablolarını çizelim:

| a | !a | a==1 | a==0 |
| 0 |  1 |   0  |   1  |
| 1 |  0 |   1  |   0  |

Gördüğünüz, gibi ave a==1eşdeğerdir ve !ave a==0ayrıca eşdeğerdir, bu yüzden yeniden yazabilir (a==0 && b==0)xor(c==1)olarak (!a && !b) xor c.

Şimdi biraz daha doğruluk tabloları:

| a | b | a xor b | a != b |
| 0 | 0 |    0    |    0   |
| 0 | 1 |    1    |    1   |
| 1 | 0 |    1    |    1   |
| 1 | 1 |    0    |    0   |

Yani a!=beşdeğerdir a xor bbiz yazabiliriz, böylece (!a && !b) xor cetmek (!a && !b)!=c. Gördüğünüz gibi, çözümleriniz tamamen farklıdır, sadece farklı 'işaretler' ile yazılmıştır.


UPD : Bahsetmeyi unuttum. Profesörün çözümünün tam olarak bu şekilde görünmesinin nedenleri var.

Profesörün çözümü daha deyimsel. Çözümünüz teknik olarak doğru olsa da, deyimsel bir C ++ kodu değildir.

İlk küçük konu türlerin kullanımıdır. Çözümün arasındaki dönüşüm dayanıyor intve boolbir dizi ya da kullanımına boole değeri karşılaştırmak xorhareket eden bir 'bit temelinde özel veya' operatörüdür, intçok s. Modern bir C ++ 'da, doğru türlerin değerlerini kullanmak ve bazen bu kadar açık ve akıl yürütmek zor olmadıkları için bu tür dönüşümlere güvenmemek çok daha takdir edilir. İçin boolbu tür değerlerin olan trueve falseyerine 1ve 0sırasıyla. Ayrıca !=, xorteknik boololarak sayılar olarak saklanırken, ancak matematiksel olarak herhangi bir sayınız yok, sadece mantıksal değerler olduğundan daha uygundur.

İkinci konu da deyim ile ilgilidir. Burada yatıyor: a == 0. Boole ifadelerini boole sabitleriyle karşılaştırmak iyi bir uygulama olarak kabul edilmez. Bildiğiniz gibi, a == trueadil olana tamamen eşdeğerdir ave a == falsesadece !aveya not a(Ben ikincisini tercih ederim). Karşılaştırmanın neden iyi olmadığını anlamak için iki kod parçacığını karşılaştırın ve karar verin, ki bu daha net:

if (str.empty() == false) { ... }

vs

if (not str.empty()) { ... }

1
Teknik olarak doğru olsa da, bu cevap, muhtemelen bu egzersizin noktası olan türler ve deyimsel C ++ hakkında konuşmaktan tamamen kaçınmaktadır.
Konrad Rudolph

@KonradRudolph, oh, evet, bundan bahsetmeyi tamamen unuttum. Belki cevabımı düzenlerim, teşekkürler
Yuri Kovalenko

3

Bitleri değil, booleanları düşünün

Özetle, profesörünüzün çözümü daha iyidir (ama yine de yanlıştır, kesinlikle konuşursak, aşağıya bakın) çünkü bitsel operatörler yerine boole işleçlerini kullanır ve boole'lara tamsayı olarak davranır. c==1"C true" yu temsil eden ifade yanlıştır, çünkü c bir sayı olabilirse (belirtilen atamaya göre), sıfır olmayan herhangi bir c değeri temsil edici olarak kabul edilecektir true.

Bunu yapmak güvenli olsa bile boolean'ları 0 veya 1 ile karşılaştırmamanın daha iyi olduğu konusunda bu soruya bakın .

Kullanmamanın çok iyi bir nedeni xor, bunun biraz akıllıca özel veya operasyon olmasıdır. Örneğinizde işe yarar çünkü hem sol hem de sağ taraf 1 veya 0'a dönüşen boole ifadeleridir (tekrar 1'e bakın ).

Boole münhasır - ya da aslında !=.

İfadeyi yıkmak

Profesörünüzün çözümünü daha iyi anlamak için, boole operatörlerini "alternatif jeton" eşdeğerleriyle değiştirmek en kolay yoldur, bu da onu daha iyi yeniden yazılabilir (imho) ve tamamen eşdeğer C ++ koduna dönüştürür: ve 've' için '&&' alırsınız

    (not a and not b) != c

Ne yazık ki, bu durumda yardımcı olmayan exclusive_orbaşka bir mantıksal operatör yoktur not_eq.

Doğal dil ifadesini yıkarsak:

A ve b'nin ikisi de yanlıştır veya c doğrudur, ancak ikisi de değildir.

ilk olarak Boole önermeleri A ve B hakkında bir cümleye:

Ya A ya da B, ama ikisi de değil.

bu A != B(sadece boolean'lar için, herhangi bir A ve B tipi için değil) anlamına gelir.

Sonra A önerisi

a ve b'nin ikisi de yanlış

olarak ifade edilebilir

a yanlış ve b yanlış

içine çevirir (not a and not b)ve nihayet

c doğrudur

Hangi basitçe çevirir c. Onları birleştirdiğinizde tekrar elde edersiniz (not a and not b) != c.

Bu ifadenin nasıl işlediğine dair daha fazla açıklama için, başkalarının cevaplarında verdiği doğruluk tablolarını erteliyorum.

İkiniz de yanılıyorsunuz

Ve eğer nitpick yapabilirsem: Orijinal atama, a, b ve c'nin negatif olmayan sayılar olabileceğini, ancak sayılar olsaydı, 0 ve 1 değerleri ile sınırlı olması gerektiğini açıkça belirtmediğini belirtti. 0 değil true, alışılmış olduğu gibi, aşağıdaki kod şaşırtıcı bir cevap verecektir :

    auto c = 2; // "true" in some way
    auto a = 0; // "false"
    auto b = 0; // "false"

    std::cout << ((!a && !b) != c);

// this will output: 1 (!)
// fix by making sure that != compares booleans:

    std::cout << ((!a && !b) != (bool)c);

Eh umarım a, bve cilan edilir boolbu durumda, c == 1olduğu doğru iğrenç kod olsa. Her neyse, bu yazdığım cevap: OP'nin kodu profesörünkine eşdeğer olabilir, ancak kötü C ++.
Konrad Rudolph

1
OP'ın atama metninin itibaren @KonradRudolph: variables are non-negative numbers or boolean. Bu yüzden + 1'den @ dhavenith'e benden, burada çoğu kişinin kaçırdığı bir detayı yakaladıkları için (başlangıçta ben dahil).
Frodyne

Harika, görüyorum. Teşekkür ederim! Ama sonra bana Profesörümün çözümünü açıklayabilir misiniz, çünkü anlamıyorum.
limonade

Profesörünüzün çözümü için alternatif bir yazım ekledim. Bu, ifadeyi netleştirmeye yardımcı olmalıdır. Daha ayrıntılı açıklamalar için, @YuriKovalenko'nun cevabındaki doğruluk tablolarının ifadeye yaklaşmanın en iyi yolu olduğunu düşünüyorum.
dhavenith

2

Bazı kelimelerle açıklamaya çalışacağım: Sayılar dolaylı olarak boole değerlerine dönüştürülebilir:

Sıfır değeri (integral, kayan nokta ve kodlanmamış numaralandırma için) ve boş işaretçi ve boş işaretçi-üye değerleri yanlış olur. Diğer tüm değerler gerçekleşir.

Cppreference kaynağı

Bu aşağıdaki sonuçlara yol açar:

  • a == 0ile aynıdır !a, çünkü abir boole'ye dönüştürülür ve sonra eşittir !(a != 0). Aynı şey b için de geçerlidir.

  • c==1zaman tek gerçek olacak c eşittir dönüştürmeyi kullanma 1. (bool)cdoğuracak truezaman c != 0sadece eğer c == 1. Bu yüzden olabilir biri genellikle temsil etmek değerini 1 kullandığından, işe true, ancak garantued değil.

  • a != ba xor bzaman ave bboolean ifadeleriyle aynıdır . Bir değer ya da diğeri doğru olduğunda doğrudur, ama ikisi de değil. Bu durumda, sol taraf (a==0 && b==0)boolean, bu yüzden sağ taraf cda boole dönüştürülür, böylece her iki taraf da boolean ifadeleri olarak yorumlanır, bu nedenle bu durumda !=olduğu gibi aynıdır xor.

Tüm bunları, diğer cevapların verdiği gerçeklerle kendiniz kontrol edebilirsiniz.


2

Doğruluk tablolarından da görebileceğimiz gibi:

  • !( not) ve ==0aynı sonuçları verir.
  • !=ve xoraynı sonuçları verir.
  • c==1 sadece aynı c

Yani biri diğerinin altında, bu 2 ifadenin neden aynı sonucu verdiğini gösteriyor:

(a==0 && b==0) xor (c==1)
(!a   && !b)   !=   c

Doğruluk tabloları:

Değil

    |   | ! |
    | 0 | 1 |
    | 1 | 0 |

== 0

    |   |==0|
    | 0 | 1 |
    | 1 | 0 |

== 1

    |   |==1|
    | 0 | 0 |
    | 1 | 1 |

Ve

   | a | b | && |
   | 0 | 0 |  0 |
   | 0 | 1 |  0 |
   | 1 | 0 |  0 |
   | 1 | 1 |  1 |

Eşit değildir

   | a | b | != |
   | 0 | 0 |  0 |
   | 0 | 1 |  1 |
   | 1 | 0 |  1 |
   | 1 | 1 |  0 |

XOR

   | a | b |xor|
   | 0 | 0 | 0 |
   | 0 | 1 | 1 |
   | 1 | 0 | 1 |
   | 1 | 1 | 0 |
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.