Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java DFS方法未生成预期输出_Java_Algorithm_Depth First Search - Fatal编程技术网

Java DFS方法未生成预期输出

Java DFS方法未生成预期输出,java,algorithm,depth-first-search,Java,Algorithm,Depth First Search,因此,我们的目标是使用dfs打印所有可能的数字,这些数字可以由电路板上的一系列相邻字符组成。我所说的相邻是指在垂直、水平或对角方向上彼此相邻。总共有8个运动方向。例句:下面的黑板 1 2 3 4 为了更简单,让我们假设我们总是从第0行第0列开始,也就是1。所以可能的数字是:1,12,13,14,123,124,132,134,142,143,1234等等(这个例子很简单,因为所有的数字都是直接相邻的) 因此,我有以下代码: static char[][] grid; static int ro

因此,我们的目标是使用dfs打印所有可能的数字,这些数字可以由电路板上的一系列相邻字符组成。我所说的相邻是指在垂直、水平或对角方向上彼此相邻。总共有8个运动方向。例句:下面的黑板

1 2
3 4
为了更简单,让我们假设我们总是从第0行第0列开始,也就是1。所以可能的数字是:1,12,13,14,123,124,132,134,142,143,1234等等(这个例子很简单,因为所有的数字都是直接相邻的) 因此,我有以下代码:

static char[][] grid;
static int rows;
static int columns;

public static void main(String[] args) {
    //test grid. made it small so that solutions are easy to count
    grid = new char[][]{
            new char[]{'1', '2'},
            new char[]{'3', '4'},
    };
    rows = grid.length;
    columns = grid[0].length;
    dfs(0, 0, new boolean[rows][columns], new StringBuilder());
}

public static void dfs(int row, int col, boolean[][] visited, StringBuilder builder){
    visited[row][col] = true;
    builder.append(grid[row][col]);
    System.out.println(builder.toString());
    //the 2 loops are for the 8 movement directions
    for(int x = -1; x <= 1; x++){
        for(int y = -1; y <= 1; y++){
            //index bounds check
            if((row + x >= 0) && (row + x < rows) && (col + y >= 0) && (col + y < columns)){
                if(!visited[row + x][col + y]){
                    dfs(row + x, col + y, visited, builder);
                    // I tried changing it so that it passes a COPY of 'visited' and 'builder',
                    // but output still the same
                    dfs(row + x, col + y, Arrays.copyOf(visited, visited.length), new StringBuilder(builder));
                }

            }
        }
    }
}
这些数字是解决方案的一部分,但远不止这些。该错误可能与将同一对象传递到递归dfs()调用有关,但我尝试对其进行更改,使其仅复制该对象,并且仍然提供相同的输出。
有什么想法吗?

您应该能够在不创建访问矩阵副本的情况下实现预期输出

重要的一点是,在每次沿着路径完成访问后,将
已访问的[row][col]
设置为
false

例如:

假设您已经遍历了'12',现在还有'3'和'4'要访问。在当前状态下,“1”和“2”的矩阵值设置为true,“3”和“4”的矩阵值设置为false。生成完以“12”开头的所有字符串后,将开始查看以“13”开头的所有字符串

但看看这里发生了什么!您已将已访问的值“2”设置为true,因此将来不会生成包含“2”的字符串

这就是为什么在从该点开始生成所有路径后,必须将
访问的[row][col]
设置为false

要真正理解这一点,请用笔和纸跟踪代码,这样您会更好地记住它

注:

实际上,在上面描述的示例中,您永远不会生成以“13”开头的字符串,因为
访问[1][1]
之前会被设置为true,因此不会再次访问3。我忽略了那个事实来说明一点

为什么我建议不要对每个递归调用进行深度复制?简单,节省时间和空间。每个调用将占用O(m*n)空间和时间来生成和存储新的访问矩阵

以下是正确代码的一个变体:

import java.util.*;

public class DFS{

    static char[][] grid;
    static int rows;
    static int columns;

    public static void main(String[] args) {
        //test grid. made it small so that solutions are easy to count
        grid = new char[][]{
                new char[]{'1', '2'},
                new char[]{'3','4'},
        };
        rows = grid.length;
        columns = grid[0].length;
        ArrayList<String>list = new ArrayList<>();
        dfs(0, 0, new boolean[rows][columns], new StringBuilder());
        //System.out.println(list);
    }

    public static void dfs(int row, int col, boolean[][] visited, StringBuilder builder){
        visited[row][col] = true;
        builder.append(grid[row][col]);
        System.out.println(builder);

        for(int x = -1; x <= 1; x++){
            for(int y = -1; y <= 1; y++){
                //index bounds check
                if((row + x >= 0) && (row + x < rows) && (col + y >= 0) && (col + y < columns)){
                    if(!visited[row + x][col + y]){
                        dfs(row + x, col + y, visited, builder);
                    }

                }
            }
        }
        visited[row][col]=false;
        builder.deleteCharAt(builder.length()-1);
    }
}
import java.util.*;
公共类DFS{
静态字符[][]网格;
静态int行;
静态int列;
公共静态void main(字符串[]args){
//测试网格。使其变小,以便于计算解决方案
网格=新字符[][]{
新字符[]{'1','2'},
新字符[]{'3','4'},
};
行=网格长度;
columns=网格[0]。长度;
ArrayList=新的ArrayList();
dfs(0,0,新的布尔值[行][列],新的StringBuilder());
//系统输出打印项次(列表);
}
公共静态void dfs(int行、int列、布尔值[][]已访问、StringBuilder){
访问[行][列]=真;
builder.append(网格[行][列]);
System.out.println(生成器);
对于(int x=-1;x=0)和&(col+y

编辑:我忘记突出显示添加的最后一行代码,在那里我删除了当前
StringBuilder
的最后一个字符。这是回溯位,因此在生成所有“12xx”字符串后,您可以删除“2”,将其替换为“3”,现在开始探索“13xx”字符串系列。

我不确定
Arrays.copyOf()
在二维数组上的行为,但它几乎肯定不会像您认为的那样。请看。幸运的是,以前有人问过一个问题,所以我不需要研究^^@JanezKuhar这很有趣。。。制作了一个手动二维阵列副本,现在可以使用了。Thx:)
import java.util.*;

public class DFS{

    static char[][] grid;
    static int rows;
    static int columns;

    public static void main(String[] args) {
        //test grid. made it small so that solutions are easy to count
        grid = new char[][]{
                new char[]{'1', '2'},
                new char[]{'3','4'},
        };
        rows = grid.length;
        columns = grid[0].length;
        ArrayList<String>list = new ArrayList<>();
        dfs(0, 0, new boolean[rows][columns], new StringBuilder());
        //System.out.println(list);
    }

    public static void dfs(int row, int col, boolean[][] visited, StringBuilder builder){
        visited[row][col] = true;
        builder.append(grid[row][col]);
        System.out.println(builder);

        for(int x = -1; x <= 1; x++){
            for(int y = -1; y <= 1; y++){
                //index bounds check
                if((row + x >= 0) && (row + x < rows) && (col + y >= 0) && (col + y < columns)){
                    if(!visited[row + x][col + y]){
                        dfs(row + x, col + y, visited, builder);
                    }

                }
            }
        }
        visited[row][col]=false;
        builder.deleteCharAt(builder.length()-1);
    }
}