路线规划器二维数组

huangapple go评论92阅读模式
英文:

Route planner two dimensional array

问题

我正在完成来自该网站 https://www.testdome.com/questions/java/route-planner/41102 的Java任务,并且卡在了ArrayIndexOutOfBoundsException错误上。当您调试代码时,我会完成,但紧接着会出现数组索引超出范围的错误。如果您打开网站,您将看到完整的任务内容,并附有图片以更好地理解。我做错了什么?

public static boolean routeExists(int fromRow, int fromColumn, int toRow,
                                  int toColumn, boolean[][] mapMatrix) {
    if (fromRow == mapMatrix.length - 1 && fromColumn == mapMatrix[0].length - 1) {
        return true;
    }

    goRight(fromRow, fromColumn, mapMatrix);
    goDown(fromRow, fromColumn, mapMatrix);

    return false;
}

private static void goRight(int one, int two, boolean[][] matrix) {
    try {
        if (two + 1 < matrix[0].length && matrix[one][two + 1]) {
            routeExists(one, two + 1, matrix.length - 1,
                    matrix[0].length - 1, matrix);
        }
    } catch (ArrayIndexOutOfBoundsException ignore) {
        System.out.println("throw ArrayIndexOutOfBoundsException");
    }
}

private static void goDown(int one, int two, boolean[][] matrix) {
    try {
        if (one + 1 < matrix.length && matrix[one + 1][two]) {
            routeExists(one + 1, two, matrix.length - 1,
                    matrix[0].length - 1, matrix);
        }
    } catch (ArrayIndexOutOfBoundsException ignore) {
        System.out.println("throw ArrayIndexOutOfBoundsException");
    }
}
英文:

I'm doing Java tasks from this website https://www.testdome.com/questions/java/route-planner/41102
and got stuck on ArrayIndexOutOfBoundsException error. When you debug code I'll get to finish, but right after that you will get array index is out of bounds. If you open website you will see full task with picture for better understanding. What am I doing wrong?

public static boolean routeExists(int fromRow, int fromColumn, int toRow,
                                  int toColumn, boolean[][] mapMatrix) {
    if (fromRow == mapMatrix.length - 1 &amp;&amp; fromColumn == mapMatrix.length - 1) {
        return true;
    }

    goRight(fromRow, fromColumn, mapMatrix);
    goDown(fromRow, fromColumn, mapMatrix);

    return false;
}

private static void goRight(int one, int two, boolean[][] matrix) {
    try {
        if (matrix[one][two + 1]) {
            routeExists(one, two + 1, matrix.length - 1,
                    matrix.length - 1, matrix);
        }
    } catch (ArrayIndexOutOfBoundsException ignore) {
        System.out.println(&quot;throw ArrayIndexOutOfBoundsException&quot;);
    }
}

private static void goDown(int one, int two, boolean[][] matrix) {
    try {
        if (matrix[one + 1][two]) {
            routeExists(one + 1, two, matrix.length - 1,
                    matrix.length - 1, matrix);
        }
    } catch (ArrayIndexOutOfBoundsException ignore) {
        System.out.println(&quot;throw ArrayIndexOutOfBoundsException&quot;);
    }
}

答案1

得分: 4

以下是翻译好的内容:

简单的解决方案以通过所有 4 个测试用例:

import java.util.*;

public class RoutePlanner {
    
    public static boolean routeExists(int fromRow, int fromColumn, int toRow, int toColumn,
                                      boolean[][] mapMatrix) {
        boolean[][] mapVisited = new boolean[mapMatrix.length][mapMatrix[0].length];
        
        return routeSearch(fromRow, fromColumn, toRow, toColumn, mapMatrix, mapVisited);
    }

    public static boolean routeSearch(int fromRow, int fromColumn, int toRow, int toColumn,
                                      boolean[][] mapMatrix, boolean[][] mapVisited) {
        
        if (fromRow < 0 || fromColumn < 0 || fromRow >= mapMatrix.length || fromColumn >= mapMatrix[0].length)
            return false;
        
        if (mapVisited[fromRow][fromColumn] || !mapMatrix[fromRow][fromColumn]
            || !mapMatrix[toRow][toColumn])
            return false;
        
        if (fromRow == toRow && fromColumn == toColumn)
            return true;
        
        mapVisited[fromRow][fromColumn] = true;
        
        return routeSearch(fromRow - 1, fromColumn, toRow, toColumn, mapMatrix, mapVisited)
            || routeSearch(fromRow, fromColumn - 1, toRow, toColumn, mapMatrix, mapVisited)
            || routeSearch(fromRow + 1, fromColumn, toRow, toColumn, mapMatrix, mapVisited)
            || routeSearch(fromRow, fromColumn + 1, toRow, toColumn, mapMatrix, mapVisited);
    }
    
    public static void main(String[] args) {
        boolean[][] mapMatrix = {
                {true, false, false},
                {true, true, false},
                {false, true, true}
        };
        System.out.println(routeExists(0, 0, 2, 2, mapMatrix));        
    }
}
英文:

Simple solution to pass all 4 test cases:

import java.util.*;
public class RoutePlanner {
public static boolean routeExists(int fromRow, int fromColumn, int toRow, int toColumn,
boolean[][] mapMatrix) {
boolean[][] mapVisited = new boolean[mapMatrix.length][mapMatrix[0].length];
return routeSearch(fromRow, fromColumn, toRow, toColumn,mapMatrix, mapVisited);
}
public static boolean routeSearch(int fromRow, int fromColumn, int toRow, int toColumn,
boolean[][] mapMatrix, boolean[][] mapVisited) {
if(fromRow &lt; 0 || fromColumn &lt; 0 || fromRow &gt;= mapMatrix.length || fromColumn &gt;= mapMatrix[0].length)
return false;
if(mapVisited[fromRow][fromColumn] || !mapMatrix[fromRow][fromColumn]
|| !mapMatrix[toRow][toColumn])
return false;
if(fromRow == toRow &amp;&amp; fromColumn == toColumn)
return true;
mapVisited[fromRow][fromColumn] = true;
return routeSearch(fromRow-1, fromColumn, toRow, toColumn, mapMatrix, mapVisited)
|| routeSearch(fromRow, fromColumn-1, toRow, toColumn, mapMatrix, mapVisited)
|| routeSearch(fromRow+1, fromColumn, toRow, toColumn, mapMatrix, mapVisited)            
||routeSearch(fromRow, fromColumn+1, toRow, toColumn, mapMatrix, mapVisited);
}
public static void main(String[] args) {
boolean[][] mapMatrix = {
{true, false, false},
{true, true, false},
{false, true, true}
};
System.out.println(routeExists(0, 0, 2, 2, mapMatrix));        
}
}

答案2

得分: 2

这是我通过了所有四个测试的答案:

import java.util.*;

public class RoutePlanner {
    
    static HashMap<String, ArrayList<String>> graph;
    
    public static boolean routeExists(int fromRow, int fromColumn, int toRow, int toColumn, boolean[][] mapMatrix) {
        if(fromRow < 0 || fromColumn < 0 || toRow < 0 || toColumn < 0) {
            return false;
        }
        if(fromRow >= mapMatrix.length || fromColumn >= mapMatrix[0].length || toRow >= mapMatrix.length || toColumn >= mapMatrix[0].length) {
            return false; 
        }
        if(!mapMatrix[fromRow][fromColumn] || !mapMatrix[toRow][toColumn]) {
            return false;
        }
        
        if(fromRow == toRow && fromColumn == toColumn) {
            return true;
        }
        
        constructGraph(mapMatrix);
        return bfs(fromRow + "-" + fromColumn, toRow + "-" + toColumn);
    }
    
    public static void constructGraph(boolean[][] mapMatrix) {
        graph = new HashMap<String, ArrayList<String>>();
        
        for(int i = 0; i < mapMatrix.length; i++) {
            for(int j = 0; j < mapMatrix[i].length; j++) {
                if(!mapMatrix[i][j]) {
                    continue;
                }
                String currId = i + "-" + j;
                if(i-1 >= 0) {
                    if(mapMatrix[i-1][j]) {
                        addEdge(currId, (i-1) + "-" + j);
                    }
                }
                if(i+1 < mapMatrix.length) {
                    if(mapMatrix[i+1][j]) {
                        addEdge(currId, (i+1) + "-" + j);
                    }
                }
                if(j-1 >= 0) {
                    if(mapMatrix[i][j-1]) {
                        addEdge(currId, i + "-" + (j-1));
                    }
                }
                if(j+1 < mapMatrix[i].length) {
                    if(mapMatrix[i][j+1]) {
                        addEdge(currId, i + "-" + (j+1));
                    }
                }
            }
        }
    }
    
    public static void addEdge(String from, String to) {
        if(graph.containsKey(from)) {
            graph.get(from).add(to);
        } else {
            ArrayList<String> neighbour = new ArrayList<String>();
            neighbour.add(to);
            graph.put(from, neighbour);
        }
    }
    
    public static boolean bfs(String start, String end) {
        LinkedList<String> queue = new LinkedList<String>();    // FIFO queue for BFS
        HashSet<String> visited = new HashSet<String>();
        
        queue.add(start);
        visited.add(start);
        
        String curr;
        while(!queue.isEmpty()) {
            curr = queue.poll();
            
            if(curr.equals(end)) {
                return true;
            }
            
            if(!graph.containsKey(curr)) {
                return false;
            }
            
            for(String next : graph.get(curr)) {
                if(!visited.contains(next)) {
                    visited.add(next);
                    queue.add(next);
                }
            }
        }
        
        return false;
    }
    
    public static void main(String[] args) {
        boolean[][] mapMatrix = {
            {true,  false, false},
            {true,  true,  false},
            {false, true,  true}
        };
        System.out.println(routeExists(0, 0, 2, 2, mapMatrix));
        
    }
}

我首先通过连接两个矩阵条目来构建图,如果它们相邻且都为 true

然后,我通过图执行一个简单的广度优先搜索(BFS),从点 (fromRow, fromColumn) 开始,在达到点 (toRow, toColumn) 时返回 true,否则返回 false

注意:我使用字符串 i + "-" + j 为矩阵中的每个点赋予一个唯一的标识符。

英文:

Here is my answer which passes all four tests:

import java.util.*;
public class RoutePlanner {
static HashMap&lt;String, ArrayList&lt;String&gt;&gt; graph;
public static boolean routeExists(int fromRow, int fromColumn, int toRow, int toColumn, boolean[][] mapMatrix) {
if(fromRow &lt; 0 || fromColumn &lt; 0 || toRow &lt; 0 || toColumn &lt; 0) {
return false;
}
if(fromRow &gt;= mapMatrix.length || fromColumn &gt;= mapMatrix[0].length || toRow &gt;= mapMatrix.length || toColumn &gt;= mapMatrix[0].length) {
return false; 
}
if(!mapMatrix[fromRow][fromColumn] || !mapMatrix[toRow][toColumn]) {
return false;
}
if(fromRow == toRow &amp;&amp; fromColumn == toColumn) {
return true;
}
constructGraph(mapMatrix);
return bfs(fromRow + &quot;-&quot; + fromColumn, toRow + &quot;-&quot; + toColumn);
}
public static void constructGraph(boolean[][] mapMatrix) {
graph = new HashMap&lt;String, ArrayList&lt;String&gt;&gt;();
for(int i = 0; i &lt; mapMatrix.length; i++) {
for(int j = 0; j &lt; mapMatrix[i].length; j++) {
if(!mapMatrix[i][j]) {
continue;
}
String currId = i + &quot;-&quot; + j;
if(i-1 &gt;= 0) {
if(mapMatrix[i-1][j]) {
addEdge(currId, (i-1) + &quot;-&quot; + j);
}
}
if(i+1 &lt; mapMatrix.length) {
if(mapMatrix[i+1][j]) {
addEdge(currId, (i+1) + &quot;-&quot; + j);
}
}
if(j-1 &gt;= 0) {
if(mapMatrix[i][j-1]) {
addEdge(currId, i + &quot;-&quot; + (j-1));
}
}
if(j+1 &lt; mapMatrix[i].length) {
if(mapMatrix[i][j+1]) {
addEdge(currId, i + &quot;-&quot; + (j+1));
}
}
}
}
}
public static void addEdge(String from, String to) {
if(graph.containsKey(from)) {
graph.get(from).add(to);
} else {
ArrayList&lt;String&gt; neighbour = new ArrayList&lt;String&gt;();
neighbour.add(to);
graph.put(from, neighbour);
}
}
public static boolean bfs(String start, String end) {
LinkedList&lt;String&gt; queue = new LinkedList&lt;String&gt;();		// FIFO queue for BFS
HashSet&lt;String&gt; visited = new HashSet&lt;String&gt;();
queue.add(start);
visited.add(start);
String curr;
while(!queue.isEmpty()) {
curr = queue.poll();
if(curr.equals(end)) {
return true;
}
if(!graph.containsKey(curr)) {
return false;
}
for(String next : graph.get(curr)) {
if(!visited.contains(next)) {
visited.add(next);
queue.add(next);
}
}
}
return false;
}
public static void main(String[] args) {
boolean[][] mapMatrix = {
{true,  false, false},
{true,  true,  false},
{false, true,  true}
};
System.out.println(routeExists(0, 0, 2, 2, mapMatrix));
}
}

I am first constructing a graph by connecting two matrix entries if they are adjacent and both are true.

Then, I am doing a simple Breadth-First Search through the graph, starting from the point (fromRow, fromColumn) and returning true once we reach the point (toRow, toColumn), or returning false otherwise.

Note: I am using a String i + &quot;-&quot; + j to give each point in the matrix a unique id.

答案3

得分: 1

使用visited辅助矩阵来防止同一步骤的无限递归的这个问题的递归解决方案:

import java.util.*;

public class RoutePlanner {

    public static boolean validMove(boolean[][] mapMatrix, boolean[][] visited, int row, int column) {
        if (row >= 0 && column >= 0 && row < mapMatrix.length && column < mapMatrix[row].length) {
            if (mapMatrix[row][column] && !visited[row][column]) // 检查移动是否有效且未访问过
                return true;
        }
        return false;
    }

    public static boolean routeExists(int fromRow, int fromColumn, int toRow, int toColumn,
                                      boolean[][] mapMatrix) {
        boolean[][] visited = new boolean[mapMatrix.length][mapMatrix[0].length];
        return routeExistsHelper(fromRow, fromColumn, toRow, toColumn, mapMatrix, visited);
    }

    public static boolean routeExistsHelper(int fromRow, int fromColumn, int toRow, int toColumn, boolean[][] mapMatrix, boolean[][] visited) {
        visited[fromRow][fromColumn] = true;
        if (fromRow == toRow && fromColumn == toColumn)
            return true;
        else {
            boolean left = false, right = false, up = false, down = false;
            if (validMove(mapMatrix, visited, fromRow + 1, fromColumn)) {
                right = routeExistsHelper(fromRow + 1, fromColumn, toRow, toColumn, mapMatrix, visited);
            }
            if (validMove(mapMatrix, visited, fromRow - 1, fromColumn)) {
                left = routeExistsHelper(fromRow - 1, fromColumn, toRow, toColumn, mapMatrix, visited);
            }
            if (validMove(mapMatrix, visited, fromRow, fromColumn + 1)) {
                up = routeExistsHelper(fromRow, fromColumn + 1, toRow, toColumn, mapMatrix, visited);
            }
            if (validMove(mapMatrix, visited, fromRow, fromColumn - 1)) {
                down = routeExistsHelper(fromRow, fromColumn - 1, toRow, toColumn, mapMatrix, visited);
            }
            return left || right || up || down;
        }
    }

    public static void main(String[] args) {
        boolean[][] mapMatrix = {
                {true, false, false},
                {true, true, false},
                {false, true, true}
        };
        System.out.println(routeExists(0, 0, 2, 2, mapMatrix));
        System.out.println(routeExists(2, 2, 0, 0, mapMatrix));
        System.out.println(routeExists(1, 1, 0, 0, mapMatrix));
        System.out.println(routeExists(1, 1, 0, 1, mapMatrix));
    }
}
英文:

My recursive solution to this question using visited helper matrix to prevent endless recursion of the same steps over and over:

import java.util.*;
public class RoutePlanner {
public static boolean validMove(boolean[][] mapMatrix,boolean[][] visited, int row, int column) {
if (row &gt;= 0 &amp;&amp; column &gt;= 0 &amp;&amp; row &lt; mapMatrix.length &amp;&amp; column &lt; mapMatrix[row].length ) {
if (mapMatrix[row][column] &amp;&amp; !visited[row][column]) // check if move is valid &amp; not visited yet
return true;
}
return false;
}
public static boolean routeExists(int fromRow, int fromColumn, int toRow, int toColumn,
boolean[][] mapMatrix) {
boolean[][] visited = new boolean[mapMatrix.length][mapMatrix[0].length];
return routeExistsHelper(fromRow,fromColumn,toRow,toColumn,mapMatrix,visited);
}
public static boolean routeExistsHelper(int fromRow, int fromColumn, int toRow, int toColumn, boolean[][] mapMatrix, boolean[][] visited) {
visited[fromRow][fromColumn] = true;
if (fromRow == toRow &amp;&amp; fromColumn == toColumn)
return true;
else {
boolean left = false, right = false, up = false, down = false;
if (validMove(mapMatrix,visited, fromRow + 1, fromColumn)) {
right = routeExistsHelper(fromRow + 1, fromColumn, toRow, toColumn, mapMatrix,visited);
}
if (validMove(mapMatrix,visited, fromRow - 1, fromColumn)) {
left = routeExistsHelper(fromRow - 1, fromColumn, toRow, toColumn, mapMatrix,visited);
}
if (validMove(mapMatrix,visited, fromRow, fromColumn + 1)) {
up = routeExistsHelper(fromRow, fromColumn + 1, toRow, toColumn, mapMatrix,visited);
}
if (validMove(mapMatrix,visited, fromRow, fromColumn - 1)) {
down = routeExistsHelper(fromRow, fromColumn - 1, toRow, toColumn, mapMatrix,visited);
}
return left || right || up || down;
}
}
public static void main(String[] args) {
boolean[][] mapMatrix = {
{true, false, false},
{true, true, false},
{false, true, true}
};
System.out.println(routeExists(0, 0, 2, 2, mapMatrix));
System.out.println(routeExists(2, 2, 0, 0, mapMatrix));
System.out.println(routeExists(1, 1, 0, 0, mapMatrix));
System.out.println(routeExists(1, 1, 0, 1, mapMatrix));
}
}

答案4

得分: -2

public class RoutePlanner {
    public static boolean routeExists(int fromRow,
                                      int fromColumn,
                                      int toRow,
                                      int toColumn,
                                      boolean[][] mapMatrix) {
        if (mapMatrix == null) {
            return false;
        }

        // Check method parameters for destination.
        if (toRow >= mapMatrix.length) {
            return false;
        }
        if (toColumn >= mapMatrix[toRow].length) {
            return false;
        }

        // Check that destination is reachable.
        if (!mapMatrix[toRow][toColumn]) {
            return false;
        }

        // Check remaining method parameters.
        if (fromRow >= mapMatrix.length) {
            return false;
        }
        if (fromColumn >= mapMatrix[fromRow].length) {
            return false;
        }

        if (!mapMatrix[fromRow][fromColumn]) {
            return false;
        }
        if (fromRow == toRow  &&  fromColumn == toColumn) {
            return true;
        }
        boolean exists = routeExists(fromRow + 1, fromColumn, toRow, toColumn, mapMatrix);
        if (!exists) {
            exists = routeExists(fromRow, fromColumn + 1, toRow, toColumn, mapMatrix);
        }
        return exists;
    }

    public static void main(String[] args) {
        boolean[][] mapMatrix = {{true, false, false},
                                 {true, true, false},
                                 {false, true, true}};

        System.out.println(routeExists(0, 0, 2, 2, mapMatrix));
    }
}
英文:

routeExists() needs to be a recursive method, i.e. a method that calls itself. When you write a recursive method you first need to write the terminating condition, i.e. if the condition is true then the method does not call itself. If the condition is false then the method should call itself but with different values for the method parameters.

In any method in java, even regular, non-recursive methods, you should always make sure that the method parameters are valid. Hence you need to first check that toRow and toColumn are valid.

You should think of the method parameters fromRow and fromColumn as the indexes of the cell in mapMatrix that you are currently in, and not where you started the matrix traversal from. Of-course, in the first call to method routeExists(), the values of parameters fromRow and fromColumn are the indexes of the start of the route.

There are five terminating conditions for method routeExists().

  1. If mapMatrix[toRow][toColumn] is false then a route does not exist, so the method must return false.
  2. If fromRow is not a valid index for mapMatrix then the method must return false. Using your example, if fromRow equals 3 then the method must return false.
  3. If fromRow is valid, then if fromColumn is not valid then the method must return false.
  4. If both fromRow and fromColumn are valid, then if mapMatrix[fromRow][fromColumn] is false, the method must return false.
  5. If mapMatrix[toRow][toColumn] is true then if fromRow equals toRow and fromColumn equals toColumn, that means you have reached the destination. In this case the method must return true.

If none of the above terminating conditions are met, then you need to progress to the next cell in mapMatrix and continue checking whether a route exists. In the code below, I arbitrarily decided to progress to the next row. If progressing to the next row does not find a route, I check the next column. Note that the order is not important. You can first move to the next column and after that move to the next row.

Here is the code.

public class RoutePlanner {
    public static boolean routeExists(int fromRow,
                                      int fromColumn,
                                      int toRow,
                                      int toColumn,
                                      boolean[][] mapMatrix) {
        if (mapMatrix == null) {
            return false;
        }

        // Check method parameters for destination.
        if (toRow &gt;= mapMatrix.length) {
            return false;
        }
        if (toColumn &gt;= mapMatrix[toRow].length) {
            return false;
        }

        // Check that destination is reachable.
        if (!mapMatrix[toRow][toColumn]) {
            return false;
        }

        // Check remaining method parameters.
        if (fromRow &gt;= mapMatrix.length) {
            return false;
        }
        if (fromColumn &gt;= mapMatrix[fromRow].length) {
            return false;
        }

        if (!mapMatrix[fromRow][fromColumn]) {
            return false;
        }
        if (fromRow == toRow  &amp;&amp;  fromColumn == toColumn) {
            return true;
        }
        boolean exists = routeExists(fromRow + 1, fromColumn, toRow, toColumn, mapMatrix);
        if (!exists) {
            exists = routeExists(fromRow, fromColumn + 1, toRow, toColumn, mapMatrix);
        }
        return exists;
    }

    public static void main(String[] args) {
        boolean[][] mapMatrix = {{true, false, false},
                                 {true, true, false},
                                 {false, true, true}};

        System.out.println(routeExists(0, 0, 2, 2, mapMatrix));
    }
}

huangapple
  • 本文由 发表于 2020年10月9日 07:50:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/64272121.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定