日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法:阶乘的五种算法

發布時間:2025/3/8 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法:阶乘的五种算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

周末溫習了一下遞歸相關的一些概念,本文先給出階乘的五種算法。

第一種實現:遞歸

1 private static long RecursiveFac(long n) 2 { 3 if (n == 0) 4 { 5 return 1; 6 } 7 else 8 { 9 return n * RecursiveFac(n - 1); 10 } 11 }

第二種實現:遞推

1 private static long Fac(long n) 2 { 3 var result = 1; 4 5 for (var i = 1; i <= n; i++) 6 { 7 result = result * i; 8 } 9 10 return result; 11 }

第三種實現:尾遞歸

1 private static int TailRecursiveFac(int n, int accumulator) 2 { 3 if (n == 0) 4 { 5 return accumulator; 6 } 7 8 return Fac(n - 1, n * accumulator); 9 }

第四種實現:消除尾遞歸

1 private static int Fac(int n, int accumulator) 2 { 3 while (true) 4 { 5 var tempN = n; 6 var tempAccumulator = accumulator; 7 8 if (tempN == 0) 9 { 10 return tempAccumulator; 11 } 12 13 n = tempN - 1; 14 accumulator = tempN * tempAccumulator; 15 } 16 }

第五種實現:堆棧(堆中分配的棧)替換函數棧

1 private enum CodeAddress 2 { 3 Start, 4 AfterFirstRecursiveCall 5 } 6 7 private class StackFrame 8 { 9 public long N { get; set; } 10 11 public long FirstRecursiveCallResult { get; set; } 12 13 public CodeAddress CodeAddress { get; set; } 14 } 15 16 private static long StackFac(long n) 17 { 18 var stack = new Stack<StackFrame>(); 19 stack.Push(new StackFrame 20 { 21 N = n, 22 CodeAddress = CodeAddress.Start 23 }); 24 25 long result = 0; 26 27 while (stack.Count > 0) 28 { 29 var current = stack.Peek(); 30 31 switch (current.CodeAddress) 32 { 33 case CodeAddress.Start: 34 if (current.N == 0) 35 { 36 result = 1; 37 stack.Pop(); 38 } 39 else 40 { 41 current.CodeAddress = CodeAddress.AfterFirstRecursiveCall; 42 stack.Push(new StackFrame 43 { 44 N = current.N - 1, 45 CodeAddress = CodeAddress.Start 46 }); 47 } 48 break; 49 case CodeAddress.AfterFirstRecursiveCall: 50 current.FirstRecursiveCallResult = result; 51 52 result = current.N * current.FirstRecursiveCallResult; 53 stack.Pop(); 54 break; 55 } 56 } 57 58 return result; 59 }

備注

這里比較有意思的實現是:尾遞歸和基于堆中的棧的遞歸,本文先不詳細介紹了,后面再細說,有興趣的朋友先看如下資源:

  • Replacing Recursion With a Stack。
  • How to replace recursive functions using stack and while-loop to avoid the stack-overflow。
  • HOW TO CONVERT A RECURSIVE ALGORITHM TO A NON-RECURSIVE ONE。
  • Replace Recursion with Iteration。
  • Provide an explanation of recursion, including an example。
  • Tail Recursion。
  • Understanding Tail Recursion。

?

總結

以上是生活随笔為你收集整理的算法:阶乘的五种算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。