【发布时间】:2011-09-28 02:37:09
【问题描述】:
我正在了解我的系统计算阿克曼算法的两个和三个参数版本的能力。对于非常小的 m 和 n 值,我的系统将计算并打印从 A0 和 A1 方法调用返回的结果。但是任何高于 3 或 4 的东西都不会返回并冻结我正在使用 atm 的终端。我的问题是我确实确定了我的机器可以计算的 m 和 n 的值。
我已经尝试了一些方法来捕获堆栈溢出,据我所知,c++ 没有我可以捕获的 stackoverflowexception。 try-catch 块不起作用。在下面的代码中,我使用 getrlimit() 来查找堆栈限制,在主 gStackRef 中创建一个地址位置。我调用 checkStack 递归地检查指向 gStackLimit 的局部变量指针。
有没有更好的方法来检查与递归方法相关的堆栈使用情况?我还要检查段故障吗?我会让你知道我在一个 unix 终端上运行。
#include <cstdlib>
#include <iostream>
#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlp);
using namespace std;
int * gStackRef;
int gStackLimit;
void checkStack(void);
int main(int argc, char *argv[])
{
int temp = 0;
gStackRef = &temp;
rlimit myl;
getrlimit(RLIMIT_STACK, &myl);
gStackLimit = (myl.rlim_cur / 3 * 8 / 10) ;/* modified for segment fault */
cout << gStackLimit << "\n";
checkStack();
}
void checkStack()
{
int temp = 0;
int* pVariableHere = &temp;
size_t stackUsage = gStackRef - pVariableHere;
printf("Stack usage: %d / %d \n", stackUsage, gStackLimit);
if(stackUsage > gStackLimit) return;
else checkStack();
}
【问题讨论】:
-
1.修复了标题拼写错误。 2. 重新标记 C++ -> C;这里没有 C++。 3. 用 POSIX 标记,因为这显然是您构建的 API。 (对于它的价值,阿克曼可能最好使用某种形式的动态编程而不是递归来计算)
-
通过动态编程,您是否建议我尝试将 A0 和 A1 的返回值保存到表中?这样我就可以在进行另一个递归调用之前检查表格并为自己节省一些空间。
-
是的,动态规划是一种表格驱动的算法求解方法。有关更多详细信息,请参阅我的答案中链接的维基百科文章。 AFAIK 你不应该需要超过
m*n的空间和时间来使用表格计算它。 (虽然我可能是错的;我自己没有实现它)考虑一个类似的情况,斐波那契数列,它需要递归计算的指数时间,但只需要使用动态规划计算的线性时间。
标签: c posix stack-overflow ackermann