二维arraylist的排列

时间:2013-10-29 08:38:09

标签: java arraylist permutation

我正在尝试制作一个二维数组列表,其中填充了每个可能的组合,例如1,2,3,4递归。 没有双倍升级。

例如,

1,0,0
2,0,0
3,0,0
4,0,0
1,2,0
1,3,0
1,4,0​​
1,2,3
等...

到目前为止我已经

//this gives me all my numbers
for(int i =0;i<arraySize;i++)
index[i] = i;

// and is the part that make the combinations
for(int i = 0;i<arraySize;i++){
   for(int x = 0;x<k;x++)
      combinations.get(i).set(x, index[i]);

编辑: 另外,我不打算打印我想将结果存储在二维数组中的结果

3 个答案:

答案 0 :(得分:2)

您要找的是Backtracking。这种解决问题的技术很大程度上基于递归。基本上,您设置了第一个数字,然后只考虑其他数字作为子问题,并且当找到第一个数字集的每个排列时,第一个数字会增加,等等。

您也可以使用直接的4 for循环来解决问题,但解决方案不会扩展到4个数字以外的其他任何内容。

您的解决方案将如下所示。它将输出4个数字的每个排列。

public class PermutationDemo {

    public static void main(String[] args) {
        int[] array = new int[4];

        for (int i=0; i<array.length; i++) {
            reset(array, i);
        }

        solve(array, 0);
    }

    private static void solve(int[] array, int i) {
        if (i == array.length) {
            print(array);
            return;
        }

        for (int k=0; k<4; k++) {
            solve(array, i+1);
            makeMove(array, i);
        }

        reset(array, i);
    }

    private static void makeMove(int[] array, int i) {
        array[i] += 1;
    }

    private static void reset(int[] array, int i) {
        array[i] = 1;
    }

    private static void print(int[] array) {
        for (int i=0; i<array.length; i++) {
            System.out.print(array[i] + " ");
        }
        System.out.println("");
    }
}

结果是:

PS [10:21] Desktop > java PermutationDemo
1 1 1
1 1 2
1 1 3
1 1 4
1 2 1
1 2 2
1 2 3
1 2 4
1 3 1
1 3 2
1 3 3
1 3 4
1 4 1
1 4 2
1 4 3
1 4 4
2 1 1
2 1 2
2 1 3
2 1 4
2 2 1
2 2 2
2 2 3
2 2 4
2 3 1
2 3 2
2 3 3
2 3 4
2 4 1
2 4 2
2 4 3
2 4 4
3 1 1
3 1 2
3 1 3
3 1 4
3 2 1
3 2 2
3 2 3
3 2 4
3 3 1
3 3 2
3 3 3
3 3 4
3 4 1
3 4 2
3 4 3
3 4 4
4 1 1
4 1 2
4 1 3
4 1 4
4 2 1
4 2 2
4 2 3
4 2 4
4 3 1
4 3 2
4 3 3
4 3 4
4 4 1
4 4 2
4 4 3
4 4 4

答案 1 :(得分:2)

另一种非递归选项。我用&#34;单词&#34; (部分)排列和&#34;符号&#34;数字:

/**
 * Expands the set of existing words by adding non-repeated symbols to their right
 * @param symbols to choose from
 * @param existing words (may include the empty word)
 * @param expanded result 
 */
public static void expand(ArrayList<Integer> symbols, 
        ArrayList<ArrayList<Integer>> existing, 
        ArrayList<ArrayList<Integer>> expanded) {
    for (ArrayList<Integer> prev : existing) {
        Integer last = prev.isEmpty() ? null : prev.get(prev.size()-1);
        for (Integer s : symbols) {
            if (last == null || s > last) {
                ArrayList<Integer> toAdd = new ArrayList<>(prev);
                toAdd.add(s);
                expanded.add(toAdd);
            }
        }
    }
}

public static void main(String[] args) {

    ArrayList<Integer> symbols = new ArrayList<>(
            Arrays.asList(new Integer[]{1, 2, 3, 4}));

    ArrayList<ArrayList<Integer>> prev = new ArrayList<>();
    ArrayList<ArrayList<Integer>> next = new ArrayList<>();
    ArrayList<ArrayList<Integer>> aux;
    ArrayList<ArrayList<Integer>> output = new ArrayList<>();
    // add empty
    prev.add(new ArrayList<Integer>());
    // expand empty, then expand that expansion, and so on and so forth
    for (int i=0; i<symbols.size(); i++) {
        expand(symbols, prev, next);
        output.addAll(next);
        aux = prev; prev = next; next = aux;
        next.clear();
    }
    // print result (note: only for debugging purposes)
    for (ArrayList<Integer> o : output) {
        for (int i : o) System.out.print(i);  System.out.println();
    }
}

输出与原始问题匹配(似乎要求实际排列,至少根据提供的示例):

1
2
3
4
12
13
14
23
24
34
123
124
134
234
1234

答案 2 :(得分:0)

作为关于java中集合操作的一般提示,我建议你查看Google Guava中的实用程序类,它可以帮助你完成大部分繁重工作,并确保你没有性能问题。不明白。

然后,下一步是寻找适合您需求的方法。例如,Collections2.permutations可能就是您要找的。

最后,如果您想将自己实现为算法练习,可以查看guava或Groove Collection API的源代码来获取想法。