【问题标题】:Can the standard Ackermann be optimized?标准的阿克曼可以优化吗?
【发布时间】:2013-12-06 05:45:20
【问题描述】:

用 Java 编写的标准阿克曼公式:

public static int ack(int x, int y) {

        if (x == 0) {
            return y + 1;
        } else if (y == 0) {
            return ack(x-1, 1); 
        } else {
            // perforce (x > 0) && (y > 0)
            return ack(x-1, ack(x,y-1));
        }
    }

我一直在想 - 是否有更快的版本来实现这一点?我在想也许有通过使用累加器或循环。

【问题讨论】:

  • 我可能会问有什么意义?我听说过的阿克曼函数唯一真正的非理论用途是作为算法运行时的上限。玩具实现是否快速真的很重要吗?
  • 我认为这里的另一个问题是你为什么今天两次问这个问题?一次用于java,一次用于scheme? stackoverflow.com/questions/20393589/…在另一个问题上,你得到的答案基本相同。

标签: java performance optimization ackermann


【解决方案1】:

是的,例如“作弊”。如果m 为5 或更高,则任何结果都不能用int 表示。对于m = 4,只能表示n < 2 案例。对于m < 4,有基于n 的简单封闭公式。

无论如何,其他一切都会溢出,所以让我们假设这些情况甚至没有发生(或者您可能会抛出错误或其他任何情况)。

未测试:

int Ackerman(int m, int n) {
    switch (m) {
    case 0:
        return n + 1;
    case 1:
        return n + 2;
    case 2:
        return n * 2 + 3;
    case 3:
        return (int)((1L << (n + 3)) - 3);
    case 4:
        return n == 0 ? 13 : 65533;
    }
}

【讨论】:

    【解决方案2】:

    我可以告诉你一件事...int 无法满足 x 和 y 的很多值

    如果您要重复调用该函数,您可以创建一个int[][] 数组来存储各种值,这样您就可以在第二次以上查找它们并且只需要计算一次。但至于加速单次执行……不确定。

    【讨论】:

      【解决方案3】:

      这种变化更快:

      public static int ack(int x, int y) {
          while (x != 0) {
              y = y == 0 ? 1 : ack(x, y - 1);
              x--;
          }
          return y + 1;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-28
        • 1970-01-01
        • 2011-09-30
        • 2012-01-31
        • 2015-07-13
        • 1970-01-01
        相关资源
        最近更新 更多