【问题标题】:Java Memoization Recursive Method [duplicate]Java记忆递归方法[重复]
【发布时间】:2018-10-29 10:49:21
【问题描述】:

一段时间以来一直试图解决这个问题,但我无法理解它。

问题:给定下面的方法。使用记忆对其进行优化。

public static long cat(int n) {
    if (n == 0)
        return 1;
    long result = 0;
    for (int i = 0; i < n; i++) {
        result += cat(i) * cat(n - i - 1);
    }
    return result;
}

我尝试过的:

private static int memCat(int n, int[] cache) {
    if (n == 0) {
        return 1;
    }

    int result = 0;

    if (cache[n] == 0) {
        for (int i = 0; i < n; i++) {
            result += memCat(i, cache) * memCat(n - i - 1, cache);
        }
        cache[n] = result;
    }

    return result;
}

我的想法是,内部 for 循环中所有计数的结果都将被保存。所以不必重复。

public static void main(String[] args) {
    System.out.println(cat(5)); //Prints 42
    System.out.println(memCat(5, new int[5 + 1])); //Prints 1 
}

我的眼睛和大脑都很累,所以这可能只是一个简单的错误。

【问题讨论】:

  • 我知道您很可能会在课堂上这样做,但对于其他参加的人,让我建议您在这样做之前非常仔细地考虑,并且可能只是不这样做。如果 Java 认为这是一个好主意,它可以并且将会为你做这种优化。使用这样的技术,你不太可能加快速度而不是减慢速度。永远不要优化,直到你无法满足要求,然后在继续这样的优化之前测量前后(即使你确实看到了改进,它可能在下一个 JRE 版本中表现不同,所以重新测试)跨度>
  • 那么明确地实现尾递归/记忆化/制表在性能方面可能会更差?
  • 如果你的虚拟机已经为你做了这件事,情况会更糟。当然,这并不总是坏事,但这种优化确实必须在你想在每种情况下使用它的现实世界中进行测试(而不是微基准测试),以确保它们确实有价值。

标签: java memoization


【解决方案1】:

你的实现的问题是你准备了cache[],但你从不使用它。这是修复方法,它相当简单:

int result = cache[n];
if (result == 0) {
    for (int i = 0; i < n; i++) {
        result += memCat(i, cache) * memCat(n - i - 1, cache);
    }
    cache[n] = result;
}

现在cache的值在之前计算过时返回,因为result在进入条件之前被赋值为cache[n]

【讨论】:

    猜你喜欢
    • 2014-05-03
    • 2017-07-07
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 2012-09-27
    • 1970-01-01
    • 2015-02-17
    相关资源
    最近更新 更多