阿克曼终止:根本原因分析

时间:2015-10-11 05:23:44

标签: c# c++ terminate termination ackermann

对于这是什么,可能不需要很多解释,它甚至可以按我想要的方式工作。我真正的问题是程序终止。我输出跟踪我的返回值和我在主函数中使用的嵌套for循环来逐步执行值。我没有理由发现这种情况,但它在最后一次通过我的循环之后大约花了10分钟来实际终止。虽然我的循环索引正在递增(因为预先检查),但我的Ackermann函数显然没有执行额外的迭代(不是我还是想要它)。另一方面,唯一合乎逻辑的解释是循环没有中断,但如果是这种情况,我的Ackermann函数应该返回一个新的b值。因此,我能想到的唯一其他原因是它采取了很长时间来清理我的数据结构并刷新内存堆的垃圾收集。对于那些不熟悉的人来说,这里的想法是实现传统上作为迭代函数的超麻烦的递归函数。递归:

给出正整数m和n: 如果m = 0,则返回n + 1;否则如果n = 0,则返回Ackermann(m - 1,1);其他人返回Ackermann(m - 1,Ackermann(m,n - 1))。所以迭代地,想法是使用堆栈来模拟递归函数调用,以便您可以使用堆中的内存,并且您不依赖于调用堆栈大小,这限制了执行时间。我担心我会忽略流量中的某些事情,导致计算完成之间的长时间延迟,以及我的程序到达用户干净退出点的时间。

这是我的代码:

 static void Main(string[] args)
    {
        ulong i, j;
        i = j = 0;
        for (i = 1; i <= 3; i++)
            for (j = 1; j <= 15; j++)
                Console.WriteLine("[{0}] Ackermann({1},{2}) = {3}", DateTime.Now, i, j, Ackermann(i, j));
        Console.WriteLine("Press any key to continue...");
        Console.ReadKey();
    }

    static ulong Ackermann(ulong a, ulong b)
    {
        Stack<ulong> ackStack = new Stack<ulong>();

        ackStack.Push(a);
        while (ackStack.Count > 0)
        {
            a = ackStack.Pop();
            if (a == 0)
                b++;
            else if (b == 0)
            {
                ackStack.Push(--a);
                b = 1;
            }
            else
            {
                ackStack.Push(--a);
                ackStack.Push(++a);
                b--;
            }
        }
        return b;
    }

思考?注意,这是c#,但在使用MinGW编译的C ++中也会出现这种情况。

1 个答案:

答案 0 :(得分:0)

非常感谢Pieter Witvoet!事实证明,我的Writeline中的评估顺序是错误的。只有在改变它之后,才会明白有多少时间会增加整个运动的整体运行时间!