2-1 阶乘(Factorial)
阶乘(Factorial)
阶乘是数学中的一个基本运算。一个非负整数 n 的阶乘,记作 n!,等于从 1 到 n 所有整数的乘积。特别地,0! = 1。
阶乘的数学定义为:
n! = n × (n-1) × (n-2) × ... × 2 × 1
例如:5! = 5 × 4 × 3 × 2 × 1 = 120
实现阶乘有两种常见方法:迭代法和递归法。
迭代法实现阶乘
迭代法使用循环结构,从 1 乘到 n,逐步累乘得到结果。
基本思路:
- 设置一个变量
result,初始值为 1。 - 使用循环从 1 遍历到 n,每次将当前值乘到
result上。 - 循环结束后,
result即为 n!。
C++ 实现
#include <iostream>
int factorial(int n)
{
int result = 1;
for (int i = 1; i <= n; i++)
{
result *= i;
}
return result;
}
int main()
{
int n = 5;
std::cout << n << "! = " << factorial(n) << "\n";
return 0;
}
运行该程序将输出
5! = 120
C 实现
#include <stdio.h>
int factorial(int n)
{
int result = 1;
for (int i = 1; i <= n; i++)
{
result *= i;
}
return result;
}
int main()
{
int n = 5;
printf("%d! = %d\n", n, factorial(n));
return 0;
}
运行该程序将输出
5! = 120
Python 实现
def factorial(n):
result = 1
for i in range(1, n + 1):
result *= i
return result
n = 5
print(f"{n}! = {factorial(n)}")
运行该程序将输出
5! = 120
Go 实现
package main
import "fmt"
func factorial(n int) int {
result := 1
for i := 1; i <= n; i++ {
result *= i
}
return result
}
func main() {
n := 5
fmt.Printf("%d! = %d\n", n, factorial(n))
}
运行该程序将输出
5! = 120
Go 中使用 for 循环实现迭代法,语法简洁,无需括号包裹条件表达式。通过 result *= i 逐步累乘,逻辑与其他语言一致。
递归法实现阶乘
递归法利用阶乘的递推性质:n! = n × (n-1)!,其中 0! = 1 作为递归的终止条件(基准情形)。
递归的两个要素:
- 基准情形(Base Case):当 n = 0 或 n = 1 时,直接返回 1。
- 递推步骤(Recursive Step):当 n > 1 时,返回 n × factorial(n - 1)。
以 factorial(5) 为例,递归调用过程如下:
factorial(5)
= 5 × factorial(4)
= 5 × 4 × factorial(3)
= 5 × 4 × 3 × factorial(2)
= 5 × 4 × 3 × 2 × factorial(1)
= 5 × 4 × 3 × 2 × 1
= 120
C++ 实现
#include <iostream>
int factorial(int n)
{
// base case
if (n <= 1)
{
return 1;
}
// recursive step
return n * factorial(n - 1);
}
int main()
{
int n = 5;
std::cout << n << "! = " << factorial(n) << "\n";
return 0;
}
运行该程序将输出
5! = 120
C 实现
#include <stdio.h>
int factorial(int n)
{
// base case
if (n <= 1)
{
return 1;
}
// recursive step
return n * factorial(n - 1);
}
int main()
{
int n = 5;
printf("%d! = %d\n", n, factorial(n));
return 0;
}
运行该程序将输出
5! = 120
Python 实现
def factorial(n):
# base case
if n <= 1:
return 1
# recursive step
return n * factorial(n - 1)
n = 5
print(f"{n}! = {factorial(n)}")
运行该程序将输出
5! = 120
Go 实现
package main
import "fmt"
func factorial(n int) int {
// base case
if n <= 1 {
return 1
}
// recursive step
return n * factorial(n-1)
}
func main() {
n := 5
fmt.Printf("%d! = %d\n", n, factorial(n))
}
运行该程序将输出
5! = 120
Go 的递归实现与其他语言类似。当 n <= 1 时返回 1(基准情形),否则返回 n * factorial(n-1)(递推步骤)。Go 不支持尾递归优化,对于大数值应优先使用迭代法。
阶乘的完整对比实现
下面我们给出一个更完整的例子,包含边界测试(0!、负数输入)和两种方法的对比。
C++ 实现
#include <iostream>
// iterative approach
int factorialIterative(int n)
{
if (n < 0)
{
std::cout << "Error: negative number has no factorial\n";
return -1;
}
int result = 1;
for (int i = 1; i <= n; i++)
{
result *= i;
}
return result;
}
// recursive approach
int factorialRecursive(int n)
{
if (n < 0)
{
std::cout << "Error: negative number has no factorial\n";
return -1;
}
if (n <= 1)
{
return 1;
}
return n * factorialRecursive(n - 1);
}
int main()
{
// test cases
int tests[] = {0, 1, 5, 10};
for (int n : tests)
{
std::cout << n << "! (iterative) = " << factorialIterative(n) << "\n";
std::cout << n << "! (recursive) = " << factorialRecursive(n) << "\n";
std::cout << "---\n";
}
// negative test
factorialIterative(-3);
return 0;
}
运行该程序将输出
0! (iterative) = 1
0! (recursive) = 1
---
1! (iterative) = 1
1! (recursive) = 1
---
5! (iterative) = 120
5! (recursive) = 120
---
10! (iterative) = 3628800
10! (recursive) = 3628800
---
Error: negative number has no factorial
C 实现
#include <stdio.h>
// iterative approach
int factorialIterative(int n)
{
if (n < 0)
{
printf("Error: negative number has no factorial\n");
return -1;
}
int result = 1;
for (int i = 1; i <= n; i++)
{
result *= i;
}
return result;
}
// recursive approach
int factorialRecursive(int n)
{
if (n < 0)
{
printf("Error: negative number has no factorial\n");
return -1;
}
if (n <= 1)
{
return 1;
}
return n * factorialRecursive(n - 1);
}
int main()
{
int tests[] = {0, 1, 5, 10};
int len = sizeof(tests) / sizeof(tests[0]);
for (int i = 0; i < len; i++)
{
int n = tests[i];
printf("%d! (iterative) = %d\n", n, factorialIterative(n));
printf("%d! (recursive) = %d\n", n, factorialRecursive(n));
printf("---\n");
}
// negative test
factorialIterative(-3);
return 0;
}
运行该程序将输出
0! (iterative) = 1
0! (recursive) = 1
---
1! (iterative) = 1
1! (recursive) = 1
---
5! (iterative) = 120
5! (recursive) = 120
---
10! (iterative) = 3628800
10! (recursive) = 3628800
---
Error: negative number has no factorial
Python 实现
def factorial_iterative(n):
if n < 0:
print("Error: negative number has no factorial")
return -1
result = 1
for i in range(1, n + 1):
result *= i
return result
def factorial_recursive(n):
if n < 0:
print("Error: negative number has no factorial")
return -1
if n <= 1:
return 1
return n * factorial_recursive(n - 1)
tests = [0, 1, 5, 10]
for n in tests:
print(f"{n}! (iterative) = {factorial_iterative(n)}")
print(f"{n}! (recursive) = {factorial_recursive(n)}")
print("---")
# negative test
factorial_iterative(-3)
运行该程序将输出
0! (iterative) = 1
0! (recursive) = 1
---
1! (iterative) = 1
1! (recursive) = 1
---
5! (iterative) = 120
5! (recursive) = 120
---
10! (iterative) = 3628800
10! (recursive) = 3628800
---
Error: negative number has no factorial
Go 实现
package main
import "fmt"
// iterative approach
func factorialIterative(n int) int {
if n < 0 {
fmt.Println("Error: negative number has no factorial")
return -1
}
result := 1
for i := 1; i <= n; i++ {
result *= i
}
return result
}
// recursive approach
func factorialRecursive(n int) int {
if n < 0 {
fmt.Println("Error: negative number has no factorial")
return -1
}
if n <= 1 {
return 1
}
return n * factorialRecursive(n-1)
}
func main() {
tests := []int{0, 1, 5, 10}
for _, n := range tests {
fmt.Printf("%d! (iterative) = %d\n", n, factorialIterative(n))
fmt.Printf("%d! (recursive) = %d\n", n, factorialRecursive(n))
fmt.Println("---")
}
// negative test
factorialIterative(-3)
}
运行该程序将输出
0! (iterative) = 1
0! (recursive) = 1
---
1! (iterative) = 1
1! (recursive) = 1
---
5! (iterative) = 120
5! (recursive) = 120
---
10! (iterative) = 3628800
10! (recursive) = 3628800
---
Error: negative number has no factorial
Go 使用切片 []int 定义测试数据,通过 range 遍历。_ 用于忽略索引(因为此处不需要)。Go 的 int 类型在 64 位系统上为 64 位,可以存储更大范围的阶乘值。
注意事项
| 问题 | 说明 |
|---|---|
| 整数溢出 | C/C++ 中 int 最大存储 2,147,483,647,约等于 12! = 479,001,600。13! = 6,227,020,800 已经溢出。需要计算更大的阶乘时,可使用 long long(最大约 20!)或 Python(原生支持大整数) |
| 递归深度 | 递归法在 C/C++ 中深度过大会导致栈溢出(Stack Overflow)。Python 默认递归深度限制为 1000,可通过 sys.setrecursionlimit() 调整 |
| 时间复杂度 | 迭代法和递归法的时间复杂度均为 O(n),空间复杂度:迭代法 O(1),递归法 O(n)(递归调用栈) |
| 尾递归 | C/C++ 编译器可能对尾递归进行优化,将递归转换为迭代,从而节省栈空间。但并非所有编译器都支持,Python 不支持尾递归优化 |

浙公网安备 33010602011771号