为什么这个memoized阶乘函数返回错误的答案!

时间:2011-04-24 12:18:34

标签: c algorithm

我已经在C中记下了阶乘函数,如下所示:

int fact(int n)
{
int temp;
int lookup_table[n];
if(lookup_table[n])
    return lookup_table[n]; 
else{
    if(n == 0 || n == 1)
        return 1;
    else
        temp = n * fact(n-1);
        lookup_table[n] = temp;
        return temp;
    }
}

但是,当我输入n = 5时,它就输出了 -1! = 134514064
有人可以解释一下发生了什么吗?

5 个答案:

答案 0 :(得分:4)

您的lookup_table数组是在本地声明的;每次调用都不同;什么都没有被记忆。

答案 1 :(得分:2)

这个int lookup_table[n];声明了一个名为lookup_table的n个int数组。由于该数组的有效索引是0..n-1,因此lookup_table [n]不在数组中,并且会导致未定义的行为。我想,你想写:int somevariable = lookup_table[n];并使用这个变量进行比较,或者根本不删除这一行。

在任何情况下,请务必在访问该阵列时检查边界。

答案 2 :(得分:2)

好吧,如果(lookup_table [n])进入一个超出lookup_table []长度的元素,马上就可以了。在C中,数组具有基于0的索引。

然后存在一个问题,即您将查找表声明为递归函数中的自动(堆栈)变量,该函数应该填充它。它需要在全局/模块范围内的函数外声明。

答案 3 :(得分:1)

替换

int lookup_table[n];

static int lookup_table[13];

这将使递归函数调用中的相同数组可访问,并为您提供足够的空间来存储int可以支持的范围内的所有因子值。

检查输入值是否为12或更小是个好主意,这样就不会遇到未定义的行为。

答案 4 :(得分:0)

int lookup_table[n]应该标记为静态(实际上它不能,你需要一个常数,但它不必太大,因为阶乘增长很快),但它不是你真正得到的原因一个错误的答案。相反,lookup_table被初始化为不确定垃圾,而不是0。

然而,当你使它静止时,没有理由将它初始化为零;这将自动完成。

哦,正如其他人所指出的,你有一个超出界限的错误,因为你需要交换int lookup_table[n]来使用常量而不是n