【问题标题】:Keeping instances of variables in recursion在递归中保持变量的实例
【发布时间】:2014-08-21 14:22:00
【问题描述】:

我正在尝试编写一个程序来查找图中的所有欧拉路径。为此,我使用了改编自此的代码:http://www.sanfoundry.com/java-program-implement-euler-circuit-problem/

我做什么:我修改了一个递归函数 printEulerUtil()(如下)用于测试并找到(方法 isValidNextEdge)可能的欧拉路径。但是,我的递归方法没有存储变量 int[][] localAdjacencyMatrix (它就像一个全局变量,我看不懂),这意味着当递归返回时(例如,在深度优先搜索中找到第一个欧拉路径之后),我的变量与最后一次递归调用相同(就像我说的,全局变量行为),而不是在程序中存储之前“原始”调用的值(第一次递归调用之前的上下文)。

我做错了什么?毕竟,递归发生时不会保存所有上下文?

这是一段代码(已注释):

// in the main call, variable vertex and localAdjacencyMatrix are defined in the constructor.
public void printEulerTourUtil(int vertex, int[][] localAdjacencyMatrix) {

        ArrayList<Integer> destinationVertexes = new ArrayList<>();
        int destination = 1;
        // print the actual vertex
        System.out.println("V: " + vertex);

        for (destination = 1; destination <= numberOfNodes; destination++) {
            // test all possibles destinations
            if (localAdjacencyMatrix[vertex][destination] == 1 && isValidNextEdge(vertex, destination, localAdjacencyMatrix)) {
                // insert these destinations in a list of next vertex for recursion
                destinationVertexes.add(destination);
                System.out.println(destination + " ");
            }
        }

        // make a recursion for every vertex destination in the list.
        for (int i = 0; i < destinationVertexes.size(); i++){
            destination = destinationVertexes.get(i);
            // go to the next vertex in the graph
            System.out.println("-> source : " + vertex + " destination " + destination);

            // localAdjacencyMatrix isn't working. it's like a global variable, so my recursion fails
            removeEdge(vertex, destination, localAdjacencyMatrix);
            printEulerTourUtil(destination, localAdjacencyMatrix);
        }

对不起,任何英语错误,任何帮助都将非常有用!谢谢!

【问题讨论】:

  • 您正在使用 localAdjacencyMatrix 递归地传递给该方法。请注意,它不是全局的,它只是传递给同一方法的引用。

标签: java recursion graph


【解决方案1】:

数组作为引用类型(与原始类型的 int 不同)。因此,每次通过递归将数组传递给方法时,您只是传递了对同一数组对象的引用。基本上,您不需要传递引用,因为所有方法调用都在获取对数组字段的引用。

如果每次调用都需要一个新的数组实例,则需要创建一个新的数组传入。

【讨论】:

  • 你是对的!我现在还有另一个问题,但我确定这在我的算法中。
【解决方案2】:

由于数组localAdjacencyMatrix 在Java 中是通过引用传递的,如果您不想修改原始数组,则需要先将其克隆到方法的顶部。但是请注意,Java clone() 方法本身不能在多维数组上工作。见how to clone multidimensional arrays

【讨论】:

    【解决方案3】:

    localAdjacencyMatrix 数组根本不是本地的。它从外部传递给第一次调用printEulerTourUtil,然后传递给每个递归调用。因此,每次递归调用都会看到并修改这个数组的同一个实例。

    另一方面,您的 destinationVertexes 变量是本地变量。它是在printEulerTourUtil 方法的范围内定义的,因此该方法的每次递归执行都会实例化该列表的一个新实例。

    我不确定你需要什么,但如果你的逻辑要求 localAdjacencyMatrix 是本地的,你应该在 printEulerTourUtil 方法中声明和实例化它。

    【讨论】:

      猜你喜欢
      • 2017-01-16
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 2020-02-11
      • 2021-12-13
      • 2012-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多