Permutation of a 2 dimensional arraylist

梦想的初衷 提交于 2020-01-13 04:26:09

问题


I'm trying to make a 2 dimensional array list that is filled with every possible combination of lets say 1,2,3,4 recursively. with no double ups.

for example.
1,0,0
2,0,0
3,0,0
4,0,0
1,2,0
1,3,0
1,4,0
1,2,3
etc...

so far I have

//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]);

EDIT: Also I'm not trying to print the result I want to store the result in a 2 dimensional array


回答1:


What you're looking for is called Backtracking. This problem-solving technique is heavily based on recursion. Basically, you set your first number, then only consider the other numbers as a sub-problem, and when every permutation has been found with that first number set, this first number is incremented, etc.

You can also solve the problem with a straight-forward 4 for-loops, but the solution will not scale to anything else than 4 numbers.

Your solution would be something like what follows. It will output every permutation of 4 numbers.

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("");
    }
}

The result is:

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



回答2:


Another, non-recursive option. I use "words" for (partial) permutations and "symbols" for numbers:

/**
 * 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();
    }
}

And the output matches the original question (which does not seem to be asking for actual permutations, at least according to the provided example):

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



回答3:


As a general tip about operations on collections in java, I would advise you to look the utility classes from Google Guava which does most of the heavy-lifting for you and ensure you don't have performance issues you don't understand.

Then, the next step is looking to find a method that suits your need. For instance, Collections2.permutations might be what you are looking for.

Finally, if you want to implement this yourself as an algorithmic exercise maybe, you can look at the source for guava or Groove Collection API to get ideas.



来源:https://stackoverflow.com/questions/19653320/permutation-of-a-2-dimensional-arraylist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!