簡體   English   中英

&&運算符的行為類似於|| 操作者

[英]&& operator behaves like || operator

我是初學者,我一直在嘗試運行一個程序,打印從1到N(用戶輸入)的所有數字,除了那些可以同時被3和7整除的數字。 然而,我的代碼所做的是它打印從1到N的數字,除了那些可被3或7整除的數字。我檢查了一段時間,我不知道它為什么這樣做。 請向我解釋我哪里出錯了。

static void Main(string[] args)
{
    int n = 0;
    int a = 0;
    n = Convert.ToInt32(Console.ReadLine());
    while (a <= n)
    {
        a++;
        if (a % 3 != 0 && a % 7 != 0)
        {
            Console.WriteLine(a);
        }
    }
    Console.ReadKey();
}

當我將if語句的符號反轉為== &&運算符正常工作時,但如果符號是!=它就像|| 操作員,這讓我更加困惑。 問題最有可能出現在這種情況下,但我看不出它有什么問題。

“除了可以同時被3和7整除的數字”之外,可以按如下方式細分:

"divisible by 3 and 7 at the same time"可表示為:

"(divisible by 3 and divisible by 7)"

"Except"可表示為"Not"

所以你得到:

Not (divisible by 3 and divisible by 7)

“可被3整除”是(a % 3) == 0

“可被7整除”是(a % 7) == 0

贈送:

Not ( (a % 3) == 0 and (a % 7) == 0)

在C#中Not變成! and成為&& ,所以你可以寫了整個事情在C#為:

if (!((a % 3) == 0 && (a % 7) == 0))


與你的錯誤比較:

if (a % 3 != 0 && a % 7 != 0)

后者是不正確的,因為它意味着:

if (the number is not divisible by 3) and (the number is not divisible by 7 )。

即它意味着"Print the number if it is neither divisible by 3 nor divisible by 7" ,這意味着"don't print the number if it's divisible by 3 or 7"

要了解原因,首先考慮數字6:

6 is not divisible by 3? = false (because 6 *is* divisible by 3)
6 is not divisible by 7? = true (because 6 is *not* divisible by 7)

所以這解決了if false and true ,這當然是false

此結果也適用於可被3整除的任何其他數字,因此不會打印3可被3整除的數字。

現在考慮數字14:

14 is not divisible by 3? = true (because 14 is *not* divisible by 3)
14 is not divisible by 7? = false (because 14 *is* divisible by 7)

所以這解決了if true and false ,這當然是false

此結果也適用於可被7整除的任何其他數字,因此不會打印7可被7整除的數字。

希望你能明白為什么現在錯了。 如果沒有,請考慮這個等效示例:


假設我們有四個人,Tom the Carpenter,Dick the Carpenter,Harry the the Butcher和Tom the Butcher。

這個問題等同於您提出的問題:

 Name every person who is (not called Tom and is not a Butcher)

你應該能夠看到這與詢問相同:

Name every person except (anyone called Tom or anyone who is a Butcher)

在這兩種情況下,答案都是Dick the Carpenter。

你應該問的問題是:

Name every person except (anyone called Tom who is also a butcher)

答案是湯姆木匠,迪克木匠和哈利屠夫。


腳注德摩根的法律

第二部法律規定:

"not (A or B)" is the same as "(not A) and (not B)"

這相當於我上面的例子,其中:

Name every person except (anyone called Tom or anyone who is a Butcher)

相當於:

Name every person who is (not called Tom and is not a Butcher)

A是anyone called Tom anyone who is a butcher而B是anyone who is a butchernot被寫成except

你應該閱讀德摩根的法律

“不(A和B)”與“(不是A)或(不是B)”相同

也,

“not(A或B)”與“(不是A)和(不是B)”相同。

a不能被3整除( a % 3 != 0 )且不能被7整除時( a % 7 != 0 ), a % 3 != 0 && a % 7 != 0為真。 因此,所有可被37整除a s (3,6,7,9,12,14,...)會使整個表達式為假。 你可以改寫它!(a % 3 == 0 || a % 7 == 0)

應該:

if ( !(a % 3 == 0 && a % 7 == 0) )
{
    Console.WriteLine(a);
}

它完全意味着:除了那些可以同時被3和7整除的數字之外的所有數字。

您還可以將其改寫為:

if ( a % 3 != 0 || a % 7 != 0 )
{
    Console.WriteLine(a);
}

你說的話:

   if not (divisible by 3 and divisible by 7) then print

你寫的:

   if not divisible by 3 and not divisible by 7 then print

不一樣的事情。 亞里士多德首先想到了這一點,奧古斯都德摩根在158年前寫了法律,將非運算符應用於操作數並反轉邏輯運算:

   if not divisible by 3 or not divisible by 7 then print

哪個產生:

   if (a % 3 != 0 || a % 7 != 0)

或者按照你說的方式寫它:

   if (!(a % 3 == 0 && a % 7 == 0))

你真正需要的是:

if ((a%21) != 0) Console.WriteLine(a);

說明:可被ab整除的數字基本上是可被abLCM整除的數字 由於3和7是素數,因此您基本上在尋找不能被3 * 7整除的數字。

查看條件語句的真值表,您可以看到if

 X(NOT multiple of 3) Y(NOT multiple of 7)   X && Y
      true                   true            'a' printed as it is not a multiple of either
      true                   false           'a' not printed, it is multiple of 7
      false                  true            'a' not printed, it is multiple of 3
      false                  false           'a' not printed, it is multiple of both 

這就是為什么不打印所有3或7或21的倍數的原因


你想要什么:數字,那是

  • 不是 (3和7的倍數) 那就是
  • !(a%3 == 0 && a%7 == 0)或甚至進一步簡化為
  • !(a%21 == 0)或甚至
  • (a%21!= 0)

a % b != 0表示“a不能被b整除”。

如果自己是不是被3整除,而不是整除7,它是由既不整除。 因此,如果它是3的倍數 7的倍數,則您的陳述將為假。

根據現實世界的事物來思考邏輯通常會有所幫助:
(請記住, true and false == falsetrue or false == true

海洋是藍色的(a可以被3整除)。
海洋不是黃色的(a不能被7整除)。

你有什么:
海洋不是藍色的,海洋不是黃色的 - 這是假的(你希望這是真的)。

你想要什么:
海洋不是(藍色和黃色) - 這是真的(海洋只有藍色,而不是藍色和黃色)。
海洋不是藍色或海洋不是黃色 - 這是真的(海洋不是黃色)。

最后兩個陳述的等價物是:

!(a % 3 == 0 && a % 7 == 0)
(a % 3 != 0 || a % 7 != 0)

你可以使用De Morgan定律將一個轉換為另一個。

如果您不知道如何實現算法,請嘗試將其分解為明顯正確的函數, 每個函數實現算法的一部分

你想“打印從1到N(用戶輸入)的所有數字,除了那些可以同時被3和7整除的數字。” 舊計時器可以使用邏輯運算符快速吐出正確有效的實現。 作為一個初學者,你可能會發現它有助於將其分解成碎片。

// write out the highest level problem to solve, using functions as
// placeholders for part of the algorithm you don't immediately know
// how to solve
for ($x = 1; $x <= $N; $x++) {
    if (is_not_divisible_by_3_and_7($x)) {
        print "$x\n";
    }
}

// then think about the function placeholders, writing them out using
// (again) function placeholders for things you don't immediately know
// how to do
function is_not_divisible_by_3_and_7($number) {
    if (is_divisible_by_3_and_7($number)) {
        return false;
    } else {
        return true;
    }
}

// keep repeating this...
function is_divisible_by_3_and_7($number) {
    if (is_divisible_by_3($number) && is_divisible_by_7($number)) {
        return true;
    } else {
        return false;
    }
}

// until you have the simplest possible functions
function is_divisible_by_3($number) {
    if ($number % 3 === 0) {
        return true;
    } else {
        return false;
    }
}

function is_divisible_by_7($number) {
    if ($number % 7 === 0) {
        return true;
    } else {
        return false;
    }
}

這更容易理解,因為每個函數都做一件事,函數名稱恰好描述了這一點。 這也滿足了編程的第一條規則:首先是正確的代碼

然后,您可以開始考慮使代碼更好,更好的意思是:

  • 更少的代碼行
  • 少計算
  • 更多評論

使用上面的代碼采用這種方法,一個明顯的改進是用通用函數替換is_divisible_by_3is_divisible_by_7

function is_divisible_by_n($number, $divisor) {
    if ($number % $divisor === 0) {
        return true;
    } else {
        return false;
    }
}

然后你可以用三元運算符替換所有大的,笨重的, if x return true else return falseif x return true else return false ,這會讓你:

function is_divisible_by_n($number, $divisor) {
    return ($number % $divisor === 0) ? true : false;
}

function is_divisible_by_3_and_7($number) {
    return (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7)) ? true : false;
}

function is_not_divisible_by_3_and_7($number) {
    return (is_divisible_by_3_and_7($number)) ? false : true;
}

現在,請注意is_not_divisible_by_3_and_7看起來與is_divisible_by_3_and_7完全相同,只是切換了返回,因此您可以將它們折疊為一個方法:

function is_not_divisible_by_3_and_7($number) {
    // look how it changed here ----------------------------------------------VVVVV - VVVV
    return (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7)) ? false : true;
}

現在,您可以利用比較本身返回值的事實,而不是使用三元運算符:

function is_divisible_by_n($number, $divisor) {
    // this expression returns a "truthy" value: true or false
    //     vvvvvvvvvvvvvvvvvvvvvvvvvv
    return ($number % $divisor === 0);
}

function is_not_divisible_by_3_and_7($number) {
    // also returns a truthy value, but inverted because of the !
    //    vvv
    return ! (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7));
}

最后,您可以使用等效的邏輯操作機械替換函數調用:

for ($x = 1; $x <= $N; $x++) {
    // all I did below was copy from the function, replace variable names
    //  v  vvvvvvvvvvvvvv    vvvvvvvvvvvvvv
    if (! (($x % 3 === 0) && ($x % 7 === 0))) {
        print "$x\n";
    }
}

作為獎勵積分,您可以應用DeMorgan的規則,通過表達式分發not:

for ($x = 1; $x <= $N; $x++) {
    if ($x % 3 !== 0 || $x % 7 !== 0) {
        print "$x\n";
    }
}

此外,您可能會發現兩個共素數具有共同因子,當且僅當它們具有N倍M的公因子時,因此:

for ($x = 1; $x <= $N; $x++) {
    if ($x % (3*7) !== 0) {
        print "$x\n";
    }
}

您可以通過使用語言的功能來更進一步地壓縮表達式:

array_walk(
    range(1, $N),
    function ($x) {
        if ($x % 21 !== 0) print "$x\n";
    }
);

等等。 關鍵是你首先要使你的代碼正確,然后你做得更好。 有時使代碼正確意味着長期和艱苦地思考。 有時它只是意味着以非常小的,非常明確的步驟寫出來。

&&與||的行為不同

要理解差異,可以使用更簡單的表達式進行一些測試:

if (true && false)
if (true || false)

因此,您的問題是了解代碼中的其他運算符(!=和%)。

將條件拆分為較小的表達式通常有助於解釋:

bool divisbleBy3 = (a % 3 == 0);
bool divisbleBy7 = (a % 7 == 0);

if (divisbleBy3 && divisibleBy7)
{
    // do not print
}
else
{
    // print
}

顯然是&&和|| 是不同的。

它聲明:if(true && false)= false if(true || false)= true

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM