如何在C++中实现阶乘函数?

19

更多类似的编程问题:http://stackoverflow.com/questions/4349505/trying-to-implement-power-and-factorial-functions-recursively-c https://dev59.com/OG445IYBdhLWcg3wOnrW https://dev59.com/BXI-5IYBdhLWcg3wNli1 - user195488
2
您的个人资料显示您是一名C#程序员;我怀疑C++设计不会有太大的区别。 - chrisaycock
1
奇怪的是,建议的重复问题中没有一个看起来真正与这个问题完全相同。其中一个问题是关于使用大数的,另一个是关于使用模板元编程的,还有一个是关于递归实现的。没有一个问题只是关于如何实现阶乘的基本问题。 - Jerry Coffin
@Jerry:如果你能计算一个大数的阶乘,那么其他东西就会迎刃而解。https://dev59.com/BXI-5IYBdhLWcg3wNli1 - user195488
1
它们都不是完全重复的,因为它们都忽略了我的关于错误处理的主要问题。 - Jonathan Allen
显示剩余3条评论
3个回答

38

递归:

unsigned int factorial(unsigned int n) 
{
    if (n == 0)
       return 1;
    return n * factorial(n - 1);
}

迭代方法:

unsigned int iter_factorial(unsigned int n)
{
    unsigned int ret = 1;
    for(unsigned int i = 1; i <= n; ++i)
        ret *= i;
    return ret;
}

编译时:

template <int N>
struct Factorial 
{
    enum { value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> 
{
    enum { value = 1 };
};

void foo()
{
    int x = Factorial<4>::value; // == 24
    int y = Factorial<0>::value; // == 1
}

这里使用了一些非常不必要的递归。 - Kyle Sletten
你也可以轻松地应用迭代方法。 - Hovhannes Grigoryan
3
错误处理在哪里? - Jonathan Allen
@Jonathan 在我的回答之后编辑了问题,并更新了错误处理要求,我想。 - Hovhannes Grigoryan

26

除了显而易见的循环和递归,现代C++编译器支持伽玛函数作为tgamma(),与阶乘密切相关:

#include <iostream>
#include <cmath>
int main()
{
    int n;
    std::cin >> n;
    std::cout << std::tgamma(n+1) << '\n';
}

测试运行:https://ideone.com/TiUQ3


这对教授如何在这种类型的函数中进行错误处理毫无用处。 - Jonathan Allen
4
@Jonathan Allen:什么样的“错误处理”?如果您想知道如何限制可接受的参数,以仅允许无符号整数,其结果可以准确表示为给定类型的值,则答案将是实现boost::math::factorial - Cubbi
@Cubbi 我相信 http://ideone.com 毁了你的代码。 - Jonathan Mee
@Cubbi,我没有权利问这个问题,但我们正在讨论您在http://en.cppreference.com上的编辑,我想您可能愿意为我们澄清一下:https://dev59.com/xZjga4cB1Zd3GeqPR_lB - Jonathan Mee

0

如果您已经安装了 Boost,您可能需要查看 boost/math/special_functions/factorials.hpp。 您可以在以下链接中阅读有关它的信息:Boost 阶乘


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接