#17524: 遞迴與邏輯運算子


nevikw39 (牜攵)

學校 : 國立臺中第一高級中學
編號 : 89903
來源 : [140.114.207.96]
最後登入時間 :
2023-05-16 17:02:16
e156. 良心題: 求和 | From: [106.107.240.213] | 發表日期 : 2019-04-17 19:13

大家安安 o'_'o

這題應該都會想到 Sigma,但是題目有不少限制。

讓我們挑戰看看吧

提示裡面說到遞迴,可是如何不用 if 終止遞迴?

C 的邏輯運算子有些特性,像是 || 在實作時只要第一個條件成立編譯器就不會理會第二個條件;同樣地,&& 在第一個條件即為偽時則直接跳過。運用此特性在大筆測資時可有效減少條件判斷之次數。

另外一個有趣的特性是,對於 C 運算式可以當作陳述式賦值的陳述式可以當作運算元。也就是說,常常有人寫出這種討人厭的寫法:

if (-1 != f = fopen(...))

{

    ...

}

利用此特性,我們同樣可以寫出這個函式 f:

int f(int x)
{
    printf("%d\n", x);
    x && f(x - 1);
    return x;
}

你大概可以想像,這個函式會遞迴 x + 1 次。

現在,你需要把他改寫為遞迴求和。

 
#18306: Re:遞迴與邏輯運算子


mirkat.ee06@g2.nctu.edu.tw (炭烤海苔)

學校 : 不指定學校
編號 : 74539
來源 : [138.246.3.200]
最後登入時間 :
2024-08-14 18:08:26
e156. 良心題: 求和 | From: [123.193.23.68] | 發表日期 : 2019-07-04 00:02

(前面恕略
 
利用此特性,我們同樣可以寫出這個函式 f:

int f(int x)
{
    printf("%d\n", x);
    x && f(x - 1);
    return x;
}

你大概可以想像,這個函式會遞迴 x + 1 次。

現在,你需要把他改寫為遞迴求和。

n大說得很好,但我看了有點久才懂,來多解釋一下好了

重點在於:&& 在第一個條件即為偽時則直接跳過

這是C的特性,為了不讓程式浪費資源所做的設計。

 

舉例來說:3 && 2 && 1 && 0 = 0 && 1 && 2 && 3 = 0

前後兩式的答案都為0,但前者 3 && 2 && 1 && 0 到最後一刻才能確定答案為0

後者 0 && 1 && 2 && 3 看到第一個0我們就可以確定答案是0了

C為了增加程式的效率,會在AND的判斷式中,看到第一個0的時候,後面全都不看了,畢竟怎麼看答案都是false阿~~

OR的情況就相反了,看到第一個1的時候,後面全都會省略。

 

但要如何把此特性運用到題目上呢?

 

x && f(x - 1);

 

玄機就在這

題目要求不要用到if,所以不能用if來判斷是否要繼續遞迴下去

n大利用 && 的特性來判斷是否要繼續遞迴

&& 在第一個條件即為偽時則直接跳過

所以當 x==0 的時候 後面的 f(x-1) 就不會執行了

(但return x 還是會執行喔)

 

如果還是不太懂的話

跑跑看下面的程式,多多觀察一下應該就會懂了^_^

#include<iostream>
using namespace std;

int f(int x)
{
    cout<<"before AND : x = "<< x << endl;
    x && f(x - 1);
    cout<<"after AND : x = "<< x <<endl;
    return x;
}

int main()
{
    f(5);
    return 0;
}

 
 
ZeroJudge Forum