大家安安 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 次。
現在,你需要把他改寫為遞迴求和。
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;
}