Reputation:
I have a specific amount of numbers. Now I want to somehow display all possible permutations of this sequence.
For example if the amount of numbers is 3, I want to display:
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 2 0
2 2 1
2 2 2
I have this code to do that where depth is the amount of numbers. Obviously this code isn't working correct. Any hints how to improve?:
for (int i = 0; i < (depth * depth); i++) {
path = setPath(depth, path, i);
print(path);
}
private static int[] setPath(int depth, int[] path, int i) {
for (int j = 1; j <= depth; j++) {
if (j == 1) {
path[depth-1] = i%depth;
} else {
path[depth-j] = i / ((j-1)*depth);
}
}
return path;
}
Upvotes: 3
Views: 1483
Reputation: 13564
You want to print permutations with length 3 of the 3 objects {0, 1, 2} allowing for repetitions. You have 3^3
of such permutations. So, the first problem with your code, is that the loop for (int i = 0; i < (depth * depth); i++) { ... }
should actually count from 0 to Math.pow(depth, depth)
. Then, a couple of remarks on the function setPath(...)
:
path
as a parameter, you'd better create a path
and return itsetPath
is convert i
into base depth
: for example, when i
is 12, you want to return [1, 1, 0]
, and 110
in base 3 (your depth) is 13 in base 10Here's your code with the changes above:
public static void main(String[] args) {
int depth = 3;
for (int i = 0; i < Math.pow(depth, depth); i++) {
int[] path = setPath(depth, i);
System.out.println(Arrays.toString(path));
}
}
private static int[] setPath(int depth, int i) {
int[] path = new int[depth];
int num = i;
int length = path.length - 1;
int index = 0;
while (num != 0) {
int remainder = num % depth;
num = num / depth;
path[length - index] = remainder;
index++;
}
return path;
}
An alternative recursive approach is:
public static void main(String[] args) {
int depth = 3;
for (int i = 0; i < Math.pow(depth, depth); i++) {
System.out.println(pad(convert(i, depth), depth));
}
}
private static String pad(String s, int b) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i <= b - s.length() - 1; i++) sb.append(0);
sb.append(s);
return sb.toString();
}
private static String convert(int n, int b) {
if (n < b)
return String.valueOf(n);
else
return convert(n / b, b) + String.valueOf(n % b);
}
where convert
performs the base conversion.
I think you can have a more efficient algorithm which count modulo depth
form 0 to depth^depth
. I have a similar algorithm for printing the elements of a cartesian product, and your problem is actually equivalent to printing the elements of the cartesian product {0, 1, 2} x {0, 1, 2} x {0, 1, 2}
.
I hope this helps.
Upvotes: 2
Reputation: 75127
I designed an approach according to that:
Let's accept that count is 3 at your example. This numbers seems like writing numbers from 0 to maximum count -at base count- with number of count step(_ , _ , _) so:
public static void main(String[] args) {
startAlgorithm(3);
}
public static void startAlgorithm(int count){
int start = 0;
int max = (int) (Math.pow(count, count) - 1);
for (int number = start; number <= max; number++) {
int[] printTo = new int[count];
int tempNum = number;
for (int i = 0; i < count; i++) {
int printInt = tempNum % count;
printTo[count - i - 1] = printInt;
tempNum /= count;
}
for (int y = 0; y < count; y++) {
System.out.print(printTo[y]);
}
System.out.println();
start++;
}
}
This solution works for every number you give as a parameter to your function and exactly prints what you want.
Upvotes: 1
Reputation: 27200
Here is some code:
public static void main(String[] args) throws IOException {
List<Number> list = new ArrayList<Number>();
list.add(0);
list.add(1);
list.add(2);
printCombinations(new ArrayList<Number>(), list, 0);
}
public static void printCombinations(List<Number> done, List<Number> numbers, int depth) {
if (numbers.size() <= depth) {
System.out.println(done); // replace with something better
} else {
for (Number r : numbers) {
List<Number> newDone = new ArrayList<Number>(done);
newDone.add(r);
printCombinations(newDone, numbers, depth + 1);
}
}
}
Prints exactly what you asked, for any number of any numbers. :)
Upvotes: 6
Reputation: 180
If you want to find all possible permutations for a non-specific length of numbers then you should use a recursive algoritm.
Upvotes: 1
Reputation: 2606
Did you look at the wikipedia page on permutations? There's at least one algorithm spelled out there.
Upvotes: 0