【问题标题】:Why does method change the boolean array parameter?为什么方法会更改布尔数组参数?
【发布时间】:2014-03-14 19:58:46
【问题描述】:

我有一门课用来寻找穿过基本迷宫的路径。迷宫与起点和终点位置一起通过路径。我使用递归来找到点之间的路径。路径作为布尔数组返回。由于某种原因,传递给 Path() 的初始迷宫发生了变化。所以我尝试制作迷宫数组的副本以避免更改任何值,但它仍然无法正常工作。

为什么 path() 会改变 open[][]?可能是这里的 C 编程让我感到困惑。

public static boolean[][] path(boolean[][] open, 
                               int start_i, int start_j, 
                               int end_i, int end_j) 
{
    int n = open.length;
    boolean[][] openCopy = new boolean[n][n]; //make a copy of open

    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            openCopy[i][j] = open[i][j]; 
        }
    } 
    return findPath(openCopy, start_i, start_j, end_i, end_j);
}

public static boolean[][] findPath(boolean[][] openCopy, int start_i, int start_j, int end_i, int end_j) 
{
    boolean[][] path = new boolean[openCopy.length][openCopy[0].length];

    if(openCopy[start_i][start_j] == false) //return false if current position is not open
        return path;
    else
        openCopy[start_i][start_j] = false;  //make current position false if not (to prevent infinite backtracking)

    if(start_i == end_i && start_j == end_j) //if end found return true
    {
        path[start_i][start_j] = true;
        return path;
    }

    path = findPath(openCopy, start_i+1, start_j, end_i, end_j); // Move North
    path = findPath(openCopy, start_i, start_j+1, end_i, end_j); // Move East
    path = findPath(openCopy, start_i-1, start_j, end_i, end_j); // Move South
    path = findPath(openCopy, start_i, start_j-1, end_i, end_j); // Move West

    return path;
}

【问题讨论】:

  • @AKS "boolean[][] openCopy = new boolean[n][n];"应该创建一个可以在不更改原始数组的情况下更改的新数组。至少我是这么认为的。
  • 您如何看待价值变化?这里不会影响数组open 传递到path()
  • @DHall 我在传递给 path() 之前打印了“open”,然后再打印它,但它不匹配。我会再次检查我的打印是否有错误。

标签: java arrays recursion boolean path-finding


【解决方案1】:

它没有,我知道这可能不是该方法的完全“适当”输入,但它证明了这一点:

public class MainForm {


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

    boolean[] [] another = path(array, 0, 0, 3, 5);

    for (boolean[] bArray : array) {
        for (boolean b : bArray) {
            System.out.println(b);
        }
    }
    System.out.println("***********************");
    for (boolean[] bArray : another) {
        for (boolean b : bArray) {
            System.out.println(b);
        }
    }
}

public static boolean[][] path(boolean[][] open, int start_i, int start_j, int end_i, int end_j) {
    int n = open.length;
    boolean[][] openCopy = new boolean[n][n]; // make a copy of open

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            openCopy[i][j] = open[i][j];
        }
    }
    return findPath(openCopy, start_i, start_j, end_i, end_j);
}

public static boolean[][] findPath(boolean[][] openCopy, int start_i, int start_j, int end_i, int end_j) {
    boolean[][] path = new boolean[openCopy.length][openCopy[0].length];

    if (openCopy[start_i][start_j] == false) // return false if current position is not open
        return path;
    else
        openCopy[start_i][start_j] = false; // make current position false if not (to prevent infinite backtracking)

    if (start_i == end_i && start_j == end_j) // if end found return true
    {
        path[start_i][start_j] = true;
        return path;
    }

    path = findPath(openCopy, start_i + 1, start_j, end_i, end_j); // Move North
    path = findPath(openCopy, start_i, start_j + 1, end_i, end_j); // Move East
    path = findPath(openCopy, start_i - 1, start_j, end_i, end_j); // Move South
    path = findPath(openCopy, start_i, start_j - 1, end_i, end_j); // Move West

    return path;
}
}

输出

false
false
true
false
false
false
false
false
true
false
false
false
false
false
true
false
false
false
false
false
true
false
false
false
***********************
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false

很明显,返回的数组和传入 path() 的数组内容不同,原始数组的原始值保持不变。我认为问题出在您的应用程序的其他地方。

【讨论】:

    【解决方案2】:

    我认为问题在于,您在内部 for 循环中传递引用。 试试这个:

    for(int j = 0; j < n; j++)
            {
                openCopy[i][j] = open[i][j]; 
            }
    

    这个:

    for (int j = 0; j < n; j++) {
        openCopy[i][j] = new Boolean(open[i][j]);
    }
    

    我认为应该有帮助。

    【讨论】:

    • 因为数组被声明为boolean[][] 而不是Boolean[][],它们应该是原语,因此不是引用。 java 会自动将基元数组中的基元装箱/拆箱吗?
    • 是的,你可能是对的。装箱拆箱在 java 中是完全自动的。正如我所经历的那样,无需担心。
    • 程序刚刚崩溃,现在路径根本不起作用:/
    • stacktrace 说什么? java.lang.ArrayIndexOutOfBoundsException?
    猜你喜欢
    • 2012-04-30
    • 2013-08-17
    • 2014-06-18
    • 2019-05-28
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    • 2020-06-20
    相关资源
    最近更新 更多