Java 如何使这个方法结束递归并达到最大值?

Java 如何使这个方法结束递归并达到最大值?,java,recursion,stack,new-operator,Java,Recursion,Stack,New Operator,在运行写给作业的解决方案时,我遇到了StackOverflower错误 以下是《Java方法:A和AB: 编写一个程序,让Cookie Monster在Cookie网格(二维数组)中找到从左上角(0,0)到右下角(大小1,大小1)的最佳路径。网格元素包含cookie(非负数)或桶(-1)。在每一步上,饼干怪兽只能向下或向右移动。不允许他踩桶。最佳路径包含最大数量的cookie 程序从文件中读取cookie网格,并报告最优路径上的cookie数量。(路径本身未报告。)JM\Ch19\exerces

在运行写给作业的解决方案时,我遇到了StackOverflower错误

以下是《Java方法:A和AB:

编写一个程序,让Cookie Monster在Cookie网格(二维数组)中找到从左上角(0,0)到右下角(大小1,大小1)的最佳路径。网格元素包含cookie(非负数)或桶(-1)。在每一步上,饼干怪兽只能向下或向右移动。不允许他踩桶。最佳路径包含最大数量的cookie

程序从文件中读取cookie网格,并报告最优路径上的cookie数量。(路径本身未报告。)JM\Ch19\exerces\cookies.dat中提供了一个示例数据文件

提示:使用堆栈。如果只有一种方法可以从当前位置继续,则转到该位置并更新cookie的累计总数。如果有两种方法继续,则保存堆栈上可能的两点之一(及其总数),然后继续到另一点。如果已到达右下角,请更新最大值。如果无处可去,检查堆栈:弹出保存的点(如果有),然后从那里继续

我们的目标是给我的老师一条最好的路径(上面有最多“饼干”的路径)

好的。因此,提到的cookie映射文件如下所示:

 1  3  0  5 -1  7 -1 -1  0  4  2  1
-1  3  2  1 -1  4 -1  5  3 -1  1  0
 5  4  8 -1  3  2  2 -1  4 -1  0  0
 2  1  0  4  1 -1  8  0  2 -1  2  5
 1  4  0  1 -1  0  3  2  2  4  1  4
 0  1  4  1  1  6  1  4  5  2  1  0
 3  2  5  2  0  7 -1  2  1  0 -1  3
 0 -1  4 -1 -1  3  5  1  4  2  1  2
 5  4  8 -1  3  2  2 -1  4 -1  0  0
 2  1  0  4  1 -1  8  0  2 -1  2  5
 1  3  0  5 -1  7 -1 -1  0  4  2  1
 0  0  3  1  5  2  1  5  4  1  3  3
这是我用来获取数字的二维数组的类(我知道这部分是有效的)。使用BlueJ调试器,二维数组似乎就是我想要的

import java.util.*;
import java.io.*;

public class MapReader
{
    public static int[][] grid;
    public static Scanner gridscanner = null;
    public static int[][] getMap()
    {
        File file = new File("cookies.dat");
        try
        {
            gridscanner = new Scanner(file);
        }
        catch (FileNotFoundException ex)
        {
            System.out.println("*** Cannot open cookis.dat ***");
            System.exit(1);
        }

        int row = 12;
        grid = new int[row][row];

        for(int r = 0; r < row; r++)
        {
            for(int c = 0; c < row; c++)
            {
                grid[r][c] = gridscanner.nextInt();
            }
        }
        return grid;
    }
}
最后,这里是我用来递归遍历2D数组的类。您会注意到,当有两条路径可用时,我更喜欢向右走,但当我从“保存”堆栈中弹出一个点时,我会向下走。据我所知,问题在于这个类:如何使方法结束其递归并达到最大值

import java.util.*;

public class CookieMonster
{
    private static int[][] map = MapReader.getMap();
    private static int max = 11;
    private static int total, maximum;
    private static Stack<Point> saved = new Stack<Point>();
    public static void main(String[] args)
    {        
        System.out.println(move(0,0));
    }

    public static int move(int r, int c)
    {
        int right = 0;
        int down = 0;
        boolean isright = true;
        boolean isdown = true;
        if (c < max)
        {
            right = map[r][c + 1];
        }
        else
            isright = false;
        if (r < max)
        {
            down = map[r + 1][c];
        }
        else
            isdown = false;
        if (right == -1)
            isright = false;
        if (down == -1)
            isdown = false;

        if (isright && isdown)
        {
            saved.push(new Point(r + 1, c, total + down));
            total += right;
            move(r, c + 1);
        }

        else if (isright)
        {
            total += right;
            move(r, c + 1);
        }

        else if (isdown)
        {
            total += down;
            move(r + 1, c);
        }

        else
        {
            if (r  == max && c == max)
            {
                if (maximum < total)
                    maximum = total;
            }
            if (!saved.isEmpty())
            {
                Point sd = saved.pop();
                total = sd.getTotal();
                move(sd.getRow(), sd.getCol());
            }
        }
        return maximum;
    }
}
import java.util.*;
公共级库克怪兽
{
私有静态int[]map=MapReader.getMap();
私有静态int max=11;
私有静态整数总计,最大值;
私有静态堆栈已保存=新堆栈();
公共静态void main(字符串[]args)
{        
系统输出println(move(0,0));
}
公共静态整数移动(整数r,整数c)
{
int right=0;
int-down=0;
布尔值isright=true;
布尔值isdown=true;
如果(c
这似乎是np完全。如果遇到死胡同,使用堆栈并编写逻辑返回到以前的路径似乎是白费力气。即使使用堆栈和逻辑,您也必须使用大量蛮力。使用一个原语来存储cookies的数量,并编写一些逻辑来随机地向下和向右移动,似乎更容易。如果你遇到了死胡同,就把结果扔掉,重新开始。如果到达终点,保存该值并检查其是否大于上一条路径。如果是的话,保留它直到你找到一个更大的。如果您运行它足够多次,您将找到最佳路径。我无法想象找到最多的cookies需要几秒钟的时间。

我知道提示建议使用堆栈,但使用堆栈可以更有效地解决此问题。它基本上是一种递归,使用以前访问过的路径的内存来避免重新计算

假设从1开始为矩阵编制索引,则成本函数应如下所示:

c(i, j) = -INF if i == 0 or j == 0 or data(i, j) < 0
          data(1, 1) if i == 1 and j == 1
          data(i, j) + min(c(i, j - 1), c(i - 1, j)) 
c(i,j)=-INF,如果i==0或j==0或数据(i,j)<0
如果i==1和j==1,则数据(1,1)
数据(i,j)+min(c(i,j-1),c(i-1,j))
您可以在通常的嵌套i-j循环中从左到右、从上到下进行迭代


c(n,n)
将为您提供最佳路径的结果。

您忘记粘贴遍历代码。您是否缺少一些代码?这不是您的代码的问题,但是
Point.getValue()
效率极低,因为它每次调用文件时都会重新读取,只是为了获得一个值。你可能会想修复它。你说它永远不会结束递归是什么意思?它覆盖了整个地图吗?它会吹坏烟囱吗?你的代码是做什么的?您发布的内容没有明显错误(我敢说)。如果有帮助的话,这个问题的确切版本:)我只是发布了实际遍历它的类。堆栈仅用于跟踪两个选项点。你能再看一看吗?好的,我最后选择了这条随机探索的路径。如果你看一下任何能解决这个问题的算法的运行时间,你会被困在二维数据结构中N次,所以运行时间是N^3。堆栈,或任何其他类型的内存,将只是系数C的一个缩减。除非C是一个大数,否则它不值得缩减,因为N^3将增长如此之快,C将是一个很小的因子。你只需要
c(i, j) = -INF if i == 0 or j == 0 or data(i, j) < 0
          data(1, 1) if i == 1 and j == 1
          data(i, j) + min(c(i, j - 1), c(i - 1, j))