保留第一次递归调用java的变量值

时间:2017-08-28 00:58:10

标签: java recursion static

所以我一直在寻找答案,我似乎无法得到一个我能理解的答案。

首先,这不是作业。这是我以前上课的一项任务,我正在刷新,因为我当时在这堂课上表现不佳。

这是一个使用递归的迷宫生成器。 我正在遵循的任务是在边界外的迷宫内部制作一个随机的水平和垂直墙,然后递归地在较小和较小的墙内进行刚刚制作的“十字架”的左上象限。从那里你将移动到其他3个象限。

所以我明白了,但我的问题是在左上象限画墙后我似乎无法找到去其他三个象限的方法。我想做其他的递归调用,但我需要从生成的第一个随机墙中的数字,位置。这样我知道第一面墙的制作位置,我可以移动到其他象限。然而,因为它是宽度和高度的X和Y位置的随机数,所以当我点击基本情况时,这些数字已经改变,我不能存储第一个。

非常感谢任何帮助!以下是我的代码。

 private static void makeMazeRecursive(char[][]level, int startX, int startY, int endX, int endY)
{   
    Random random = new Random();
    int randRow = random.nextInt(endY - startY) + 2;
    int randColumn = random.nextInt(endX - startX) + 2;
    int randColumnSpace = random.nextInt(endY + 2) + 2;
    int randRowSpace = random.nextInt(endX + 2) + 2;

    System.out.println("randRow: " + randRow + " randColumn: " + randColumn );
    System.out.println("firstRandRow: " + firstRandRow + " firstRandCol: " + firstRandCol);

    if(endX > 2 && endY > 2) {
        for(int column = startY; column <= endY; column++) {
            level[column][randColumn] = '#';
            level[randColumnSpace][randColumn] = ' ';
            for(int row = startX; row <= endX; row++) {
                level[randRow][row] = '#';
                level[randRow][randRowSpace] = ' ';
            }
    }

    System.out.println("startX: " + startX + " endX: " + endX );
    System.out.println("startY: " + startY + " endY: " + endY );

    makeMazeRecursive(level, 1, 1, randColumn, randRow);
    //makeMazeRecursive(level, firstRandRow, LEVEL_WIDTH - 1, firstRandCol, 0);
    }

}

2 个答案:

答案 0 :(得分:2)

看看你手头的问题,似乎可以通过迭代轻松解决。

  • 逐个遍历所有单元格,随机将#<space>放入单元格中。
  • 您可以为单元格添加<space>的机会高于添加{{1}的机会,从而构建更多方式和更少 }。
  • 最后将迷宫构建规则付诸实施 - 例如确保未指定开始和结束{。{1}}。

然后你准备好了迷宫!

您当前代码的问题表示您递归下降到较小尺寸的象限,但象限的基本大小最终可能小于您想要的象限的最小尺寸。

有两种方法可以解决这个问题:

  1. 当您选择##时,请确保由于这些值而构建的4个象限对于您的迷宫构建代码来说足够大; OR,
  2. 修改您的代码,以便它可以在所有大小的象限中构建迷宫 - 这实际上意味着您可以在单个单元格中构建迷宫。
  3. 如果您将深入探索两种方式,您会发现在两种情况下,您实际上只会触摸迷宫中的每个细胞一次。那么,为什么不逐个遍历单元格并迭代地编写代码呢?但是,这只是我的建议。

    为了帮助您改进当前的代码,我希望以下递归设计是有意义的:

    randRow

答案 1 :(得分:1)

你是不是很清楚你是如何尝试接近这个的;我不知道它将如何产生迷宫。

但是,如果我理解你要说的部分内容,那么我认为你对递归的工作方式存在根本的误解。假设您进行了这些递归调用:

makeMazeRecursive(level, startX, startY, randColumn, randRow);
makeMazeRecursive(level, randColumn, startY, endX, randRow);
makeMazeRecursive(level, startX, randRow, randColumn, endY);
makeMazeRecursive(level, randColumn, randRow, endX, endY);

以下是发生的事情:

       startX              randColumn            endX
startY    +---------------------|------------------+
          |        (1)          |       (2)        |
          |                     |                  |
randRow   +---------------------+------------------+
          |                     |                  |
          |        (3)          |       (4)        |
          |                     |                  |
endY      +---------------------+------------------+

您将按顺序在象限1,2,3,4上递归调用该方法。

如果您认为这不会起作用,因为递归调用会改变数字 - 这就是您存在根本误解的地方。 每个递归调用都保留自己的参数和局部变量的副本。因此,如果使用(3,4,17,20)调用makeMazeRecursive,它将startX = 3,{{ 1}} = 4,startY = 17,endX = 20。它计算两个局部变量endYrandColumn。然后,当它第一次递归调用randRow时,新makeMazeRecursive将拥有自己的makeMazeRecursivestartXstartY和{{1} },以及它自己的endXendY - ,但它不会触及属于原始调用的变量。因此,当randColumn返回时(可能在调用其自身的许多其他递归调用之后),randRowmakeMazeRecursivestartXstartYendX ,和endY将与递归调用开始之前的相同。所以第二次递归调用将正常工作,在象限(2)中创建一个较小的迷宫。当递归调用返回时,这6个变量仍然是相同的,下一个调用将在象限(3)等中起作用。

这适用于局部变量和参数。它不适用于静态变量,这就是为什么它不能用于那些(假设你正在尝试做我认为你正在尝试做的事情)。

请注意,我仍然不了解算法。这意味着在上面的递归调用中,您可能需要为某些行和列变量添加+1或-1。你必须自己解决这个问题。

更多:我没有仔细查看其余的逻辑。但是为了使事情有效,当你递归调用你的方法在象限中生成一个迷宫时,递归方法必须确保它只在那个象限内工作。这意味着您的随机列必须介于randColumnrandRow之间,随机行必须介于startXendX之间。所以这些都是错的:

startY

因为您可能会在象限外生成一行和一列。相反,您需要确保endYint randRow = random.nextInt(endY - startY) + 2; int randColumn = random.nextInt(endX - startX) + 2; 在范围内,可能是这样的:

randRow

(???表示可能你必须包含+1或+2或-1或-2;我仍然不知道你的算法是如何工作的,所以你需要工作那个更好的是,按照displayName&#39的答案中的建议定义一个方法randColumn,这样可以更清楚地了解正在发生的事情。