新手编程:非i*factorial(i-1)的递归阶乘代码正确性验证请求
你的递归阶乘实现分析
你的这段代码能得到正确结果,但存在严重的问题:
未初始化变量
TotalFact
虽然循环最后一次赋值会覆盖掉垃圾值,但这是依赖编译器行为的危险写法,一旦循环逻辑出现偏差,就会返回随机垃圾值,不符合编程规范。递归效率极低,重复计算严重
比如计算factorial(5)时,程序会反复调用factorial(4)、factorial(3)等子函数无数次——factorial(4)内部会调用factorial(3),factorial(5)的循环里也会单独调用factorial(3),完全是重复计算,时间复杂度直接飙升到O(n!),而正常递归阶乘的时间复杂度仅为O(n),这种写法完全没必要。逻辑冗余
你把递归和循环混在一起,把简单的阶乘问题复杂化了,既没发挥递归的简洁性,也没利用循环的高效性。
符合你需求的替代实现
如果你不想用i * factorial(i - 1)这种经典递归写法,可以试试尾递归的实现方式,它通过累积参数传递结果,写法和经典递归不同,而且效率更高(部分编译器可以优化尾递归为循环):
#include<stdio.h> // 辅助函数,用accumulator累积结果 int factorial_helper(unsigned int n, int accumulator); int factorial(unsigned int n) { // 初始累积值为1 return factorial_helper(n, 1); } int factorial_helper(unsigned int n, int accumulator) { // 终止条件:n<=1时返回累积的结果 if (n <= 1) { return accumulator; } // 尾递归调用:把当前n乘到累积值里,n减1 return factorial_helper(n - 1, n * accumulator); } int main(void) { printf("Fact: %d", factorial(5)); return 0; }
这种写法没有直接用n * factorial(n-1)的形式,而是通过辅助函数的累积参数来传递中间结果,既满足你的需求,又保证了效率和正确性。
另外注意:原代码中unsigned int类型的参数搭配int返回值,当n超过12时(12! = 479001600,超过int的最大值2147483647)会发生溢出,建议将返回值改为unsigned int或者long long避免溢出问题。
内容的提问来源于stack exchange,提问作者user20940494
相关产品推荐
相关产品推荐

