Permutation without repetition is based on the theorem that the number of results is a factorial of the number of elements (in this case, numbers). In your case 10! 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 3628800. The proof that this is accurate is the right solution for the generation. Well, since. In the first position, i.e. On the left, you can have 10 numbers, and in the second position you can only have 9 numbers, because one number is in the position on the left, and we cannot repeat the same number, etc. (The proof is carried out using mathematical induction). So how to generate the first ten results? According to my knowledge, the easiest way is to use a cyclic shift. This means that the order of shifting the number to the left is one position (or to the right, if you want), and a number that overflows to put in an empty place. This means that for the first ten results:
10 9 8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1 10
8 7 6 5 4 3 2 1 10 9
7 6 5 4 3 2 1 10 9 8
6 5 4 3 2 1 10 9 8 7
5 4 3 2 1 10 9 8 7 6
...
The first line is the base sample, so it is recommended to add it to the set before generation. The advantage is that in the next step you have to solve the same problem to avoid unwanted duplicity.
In the next step, recursively rotate only 10-1 numbers 10-1 times, etc. This means that the first 9 results in the second step:
10 9 8 7 6 5 4 3 2 1
10 8 7 6 5 4 3 2 1 9
10 7 6 5 4 3 2 1 9 8
10 6 5 4 3 2 1 9 8 7
10 5 4 3 2 1 9 8 7 6
...
etc., note that the first line is present from the previous step, therefore it cannot be added to the generated set again.
The algorithm recursively does just that, as explained above. You can create all combinations of 3628800 for 10 !, because the number of attachments is the same as the number of elements in the array (this means that in your case for 10 numbers it lingers for about 5 minutes on my computer), and you need to have enough memory if you want to save all combinations in an array.
There is a solution.
package permutation; /** Class for generation amount of combinations (factorial) * !!! this is generate proper permutations without repeating and proper amount (počet) of rows !!! * * @author hariprasad */ public class TestForPermutationII { private static final String BUMPER = "*"; private static int counter = 0; private static int sumsum = 0; // definitoin of array for generation //int[] testsimple = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int[] testsimple = {1, 2, 3, 4, 5}; private int ELEMNUM = testsimple.length; int[][] shuff; private String gaps(int len) { String addGap = ""; for(int i=0; i <len; i++) addGap += " "; return addGap; } /** Factorial computing */ private int fact(int num) { if (num > 1) { return num * fact(num - 1); } else { return 1; } } /** Cyclic shift position to the left */ private int[] lShiftPos(int[] arr, int pos) { int[] work = new int[ELEMNUM]; int offset = -1; for (int jj = 0; jj < arr.length; jj++) { if (jj < pos) { work[jj] = arr[jj]; } else if (jj <= arr.length - 1) { if (jj == pos) { offset = arr[pos]; // last element } if (jj != (arr.length - 1)) { work[jj] = arr[jj + 1]; } else { work[jj] = offset; } } } return work; } private String printBuff(int[] buffer) { String res = ""; for (int i= 0; i < buffer.length; i++) { if (i == 0) res += buffer[i]; else res += ", " + buffer[i]; } return res; }; /** Recursive generator for arbitrary length of array */ private String permutationGenerator(int pos, int level) { String ret = BUMPER; int templen = counter; int[] work = new int[ELEMNUM]; int locsumread = 0; int locsumnew = 0; //System.out.println("\nCalled level: " + level); for (int i = 0; i <= templen; i++) { work = shuff[i]; sumsum++; locsumread++; for (int ii = 0; ii < pos; ii++) { counter++; sumsum++; locsumnew++; work = lShiftPos(work, level); // deep copy shuff[counter] = work; } } System.out.println("locsumread, locsumnew: " + locsumread + ", " + locsumnew); // if level == ELEMNUM-2, it means no another shift if (level < ELEMNUM-2) { ret = permutationGenerator(pos-1, level+1); ret = "Level " + level + " end."; //System.out.println(ret); } return ret; } public static void main(String[] argv) { TestForPermutationII test = new TestForPermutationII(); counter = 0; int len = test.testsimple.length; int[] work = new int[len]; test.shuff = new int[test.fact(len)][]; //initial test.shuff[counter] = test.testsimple; work = test.testsimple; // shalow copy test.shuff = new int[test.fact(len)][]; counter = 0; test.shuff[counter] = test.testsimple; test.permutationGenerator(len-1, 0); for (int i = 0; i <= counter; i++) { System.out.println(test.printBuff(test.shuff[i])); } System.out.println("Counter, cycles: " + counter + ", " + sumsum); } }
The intensity (number of cycles) of the algorithm is the sum of the incomplete factorials of the number of members. Thus, there is an overhang when a partial set is read again to generate the next subset, so the intensity:
P! + n! / 2! + n! / 3! + ... + n! / (n-2)! + n! (n-1)!