![](/img/trans.png)
[英]Why is factorial recursive function less efficient than a normal factorial function?
[英]why is this factorial recursive function inefficient?
在“像程序員一樣思考”一書中,下面的遞歸函數被稱為“非常低效”,我無法弄清楚為什么(這本書沒有解釋)。 似乎沒有任何不必要的計算。 是因為調用這么多函數(多次使用相同的函數)的開銷,從而為每次調用函數設置環境?
int factorial(int n) {
if (n == 1) return 1;
else return n * factorial(n-1);
}
它在兩個方面效率低下,你打其中一個:
它是遞歸的,而不是迭代的。 如果未啟用尾調用優化,則效率非常低。 (要了解有關尾調用優化的更多信息,請查看此處 。)它可以像這樣完成:
int factorial(int n)
{
int result = 1;
while (n > 0)
{
result *= n;
n--;
}
return result;
}
或者,使用for
循環。
但是,正如上面的評論中所指出的,如果int
甚至無法保持結果,那么它的效率並不重要。 它應該是long
的, long long
的,甚至是大的。
第二個低效率只是沒有一個有效的算法。 這個因子算法列表顯示了一些通過減少數值運算的數量來計算因子的更有效方法。
當不使用實現尾調用優化的編譯器時,C中存在顯着的函數調用開銷。
函數調用開銷是計算機正確設置函數調用所需的額外時間和內存。
尾調用優化是一種將遞歸函數轉換為循環函數的方法。
我認為書籍作者可能想告訴讀者不要濫用遞歸。 對於此功能,您可以使用:
int factorial(int n) {
int res = 1;
for (i = 1; i <= n; i++) {
res = res * i;
}
return res;
}
就內存堆棧而言,遞歸速度較慢,內存也較慢。這是一個將信息推送到堆棧並再次彈出它的時間。遞歸的主要優點是它使算法更容易理解或更多“優雅”。
為了找到階乘,我們可以使用For循環,它在內存和時間復雜度方面都很好。
int num=4;
int fact = 1;
for (;num>1;num--)
{
fact = fact*num;
}
//display fact
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.