问题
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