【问题标题】:Calculate all array elements combinations recursively issue递归计算所有数组元素组合
【发布时间】:2017-11-23 23:08:47
【问题描述】:

我有一个程序,给定一个数组,返回其值的所有可能组合(排列?)。我递归地这样做。它计算得很好,但是,我想做的是,不是每次迭代都打印结果数组,而是想将它附加到我之前声明的数组列表中。

public static final int NUMBER_OF_CELLS = 3;
public static final int NUMBER_OF_ATTRIBUTES = 3;
// I want all possible combinations all elements 0, 1 and 2, taken 3 at a time 

private ArrayList<State> states= new ArrayList<State>();

public void createAllPossibleStates() {
        State state = new State(NUMBER_OF_CELLS);
        setValues(0, state);
        System.out.println(states);  // This gives me a wrong ouput and I don't know why
    }

public void setValues(int cell, State state) {
        if(cell == NUMBER_OF_CELLS) {
                // System.out.println(state.toString());  // Instead of this
                states.add(state);  // I want this. Append the array to an array list
            }
        }
        else {
            for(int i = 0; i < NUMBER_OF_ATTRIBUTES; i++) {
                state.values[cell] = i;
                setValues(cell + 1, state);
            }
        }
    }

但是最终的 Array List 包含所有可能的状态的结果是错误的。而不是这个:

[[0, 0, 0],[0, 0, 1],[0, 0, 2],[0, 1, 0],[0, 1, 1],[0, 1, 2],[0, 2, 0],[0, 2, 1],[0, 2, 2],[1, 0, 0],[1, 0, 1],[1, 0, 2],[1, 1, 0],[1, 1, 1],[1, 1, 2],[1, 2, 0],[1, 2, 1],[1, 2, 2],[2, 0, 0],[2, 0, 1],[2, 0, 2],[2, 1, 0],[2, 1, 1],[2, 1, 2],[2, 2, 0],[2, 2, 1],[2, 2, 2]]

我明白了:

[[2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2]]

我不知道为什么会这样。也许递归事实导致附加操作以错误的方式工作?

【问题讨论】:

    标签: java arrays recursion combinations permutation


    【解决方案1】:

    嗨,

    您总是将相同的 State 对象添加到 ArrayList。 每个递归循环都在修改同一个 State 对象。

    必须在 State 类中实现克隆:

    @Override
    protected State clone() throws CloneNotSupportedException {
        State state = new State(NUMBER_OF_CELLS);
        System.arraycopy(this.values, 0, state.values, 0, this.values.length);
    
        return state;
    }
    

    并将states.add(state); 替换为states.add(state.clone());

    【讨论】:

    • 感谢您的回答。您对此有可能的解决方案吗?至少现在,我不知道如何解决这个问题......
    • 看看答案,希望对您有所帮助!
    【解决方案2】:

    您只有 1 个 State 实例,并且您将其通过调用堆栈向下传递,对其进行修改,然后将其多次添加到列表中(每个递归终止一个)。当然,由于只涉及一个对象,因此它将具有任何状态(没有双关语)是最后给予它的状态。

    在不修改太多代码的情况下,您需要复制State 对象并将copy 添加到列表中 - 以永久捕获您将其添加到列表时的状态.

    有一些标准方法可以做到这一点,但也许最容易理解和最常用的是复制构造函数

    public State(State state) {
        this.values = Arrays.copyOf(state.values, state.values.length);
        // copy over whatever other fields you need
    } 
    

    然后在你的代码中:

    states.add(new State(state));
    

    【讨论】:

      猜你喜欢
      • 2019-09-26
      • 1970-01-01
      • 2015-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多