递归网格计数器

时间:2016-01-11 15:13:26

标签: java arrays recursion matrix

在你们问任何人之前,这不是家庭作业。我从他的计算机科学课上得到了我的兄弟姐妹这个实验室,他也给了我,因为我也在学习Java。以下是lab_ https://drive.google.com/open?id=0B0knwQqYII5BekhuTDFxcER3Qk0的word文件的链接。我主要关心的是如何使用递归方法来导航网格。我打算通过将它们改为$符号来标记计数的@符号,但我不确定我的递归方法应该返回什么坐标。

非常感谢任何帮助,谢谢!

2 个答案:

答案 0 :(得分:1)

尝试类似:

char[][] table = // ...

private static int countConnectedSigns(char[][] table, int r, int c) {
    char[][] tableCopy = // ...
    return countConnectedSignsAux(tableCopy[][], r, c, 0);
}

private static int countConnectedSignsAux(char[][] table, int r, int c, int currentCount) {
    if(r < 0 || r >= table.length || c < 0 || c >= table[0].length ||
       table[r][c] != '@') {
        return currentCount;
    }
    table[r][c] = '-';    // mark visited
    return countConnectedSignsAux(table, r + 1, c, currentCount + 1) +
        countConnectedSignsAux(table, r - 1, c, currentCount + 1) +
        countConnectedSignsAux(table, r, c + 1, currentCount + 1) +
        countConnectedSignsAux(table, r, c - 1, currentCount + 1) +;
}

答案 1 :(得分:0)

和你一样,我是Java编程的新手,所以对我来说这是一个很好的练习。谢谢! 这是我的解决方案。如果您有任何问题,请告诉我。

下面是两个.java文件的链接,以获得问题的完整解决方案。该解决方案未经过广泛测试,因此可能存在模糊错误,但它使用简单的递归解决了这个问题,相当直观,并且包含了完整工作示例所需的管道代码。这是第一次尝试的解决方案,它无论在效率还是编码风格上都可以得到改进。

https://drive.google.com/folderview?id=0BxpVs-UD4OcwRjd2TjNtaEJndXc&usp=sharing

这是算法的伪代码。关键方法是getOccupiedNeighbors()recursiveFind()。邻居方法使用四个硬编码检查来查找北,东,南和西方格。它首先检查以确保任何潜在的邻居都在边界内,然后查看邻居是否被占用&#34;。

递归方法询问是否已经检查了当前方块(&#34;已访问&#34;)。如果没有,则计数增加,其邻居被添加到列表中,并且方块被标记为已访问。然后该方法在列表中的每个方块上递归调用自身,直到所有列表都没有被访问的,被占用的邻居为止。

class Grid

HEIGHT = 10;
WIDTH = 20;
OCCUPIED_SYMBOL = "@";
EMPTY_SYMBOL = "-";
WEIGHT = 0.5f;

occupiedCount = 0;

grid = new String[HEIGHT][WIDTH];
visited = new boolean[HEIGHT][WIDTH];


toString()
    format for console output

randomize()
    for each SQUARE : GRID
        if random() < WEIGHT  then SQUARE.text = SYMBOL 

isOccupied(row, column)
    return (GRID[location] == SYMBOL)

getOccupiedNeighbors(row, column)
    //North
    if (ROW - 1 >= 0) & isOccupied()
        add Coordinate to list

    //South, West, East
    if (ROW + 1 > HEIGHT) {...}
    if (COLUMN - 1 >= 0) {...}
    if (COLUMN + 1 > WIDTH) {...}

    return LIST 

findSequence(row, column)
    reset OCCUPIED_COUNT and VISITED
    recursiveFind(currentSquare) // Start the process
    return OCCUPIED_COUNT

recursiveFind(row, column)
    if currentSquare has not been visited yet
        list = getOccupiedNeighbors()
        mark currentSquare as visited
        increase count

    for each SQUARE in LIST
        resursiveFind(SQUARE)

该算法相当有效,但其性能可以通过几种方式得到改善。首先,可以更好地处理对邻居的边界检查。硬编码,可重复的序列对我来说通常是代码味道。其次,使用先前访问过的位置数组可能不是限制递归的最有效方法。我不确定这个,但我认为以一种消除查看任何先前检查的邻居的可能性的方式构建递归方法可能更有效。

该示例的面向对象也可以进行相当多的改进。有一个Coordinate类,但它只在一个地方使用。所有(row, column)参数都应替换为(Coordinate c)。这将消除良好的错误来源。访问修饰符,实例字段,mutator和访问器以及其他标准OO功能等内容完全缺失。

希望这会有所帮助。如果您在运行代码时遇到任何问题或疑问,请与我们联系。