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 不支持尾递归优化
posted @ 2026-04-16 10:32  游翔  阅读(20)  评论(0)    收藏  举报