0

I want a program that takes in an 8 digits number and return all permutations of it.

For instance, 12345678 should return 12345687, 12345768, 12345786 .. 87654321.

My idea is to do this:

First put every digit as a element in an array and then:

for (int y = 0; y < digits; y++)
    for (int x = 0; x < digits; x++)
        for (int u = 0; u < digits; u++)
            for (int m = 0; m < digits; m++)
                for (int z = 0; z < digits; z++)
                    for (int b = 0; b < digits; b++)
                        for (int c = 0; c < digits; c++)
                            for (int d = 0; d < digits; d++)
                            {
                                if (!(y == x || y == u || y == m
                                    || y == z || y == b || y == c
                                    || y == d || x == u || x == m
                                    || x == z || x == b || x == c
                                    || x == d || u == m || u == z
                                    || u == b || u == c || u == d
                                    || m == z || m == b || m == c
                                    || m == d || z == b || z == c
                                    || z == d || b == c || b == d || c == d))
                                {

                                    holding[co] = (a1[y] * 10000000)
                                                + (a1[x] * 1000000)
                                                + (a1[u] * 100000)
                                                + (a1[m] * 10000)
                                                + (a1[z] * 1000)
                                                + (a1[b] * 100)
                                                + (a1[c] * 10)
                                                +  a1[d];

                                    co++;
                                }
                            }

And get all of the result into an array. Sort the array and get rid of the same elements (like if input is 11223344 then there will be same elements).

But the problem is I actually want to print all of permutations of numbers from 10000000 to 20000000. This idea works too slow. Does anyone know how to do it more quickly?

Khaled.K
  • 5,828
  • 1
  • 33
  • 51
Sdiao
  • 13
  • 2
  • 1
    "All permutations of numbers from 10000000 to 2000000" - perish the thought, all the paper in the world won't hold the result. – laune Jan 10 '15 at 20:27
  • Or do you mean those numbers resulting from the permutations of the digits 1 to 8 where the first digit is 1? – laune Jan 10 '15 at 20:29
  • to hold all permutations from 1 million to 2 million is the factorial of 1 million way too big for any collection in any programming language, even if outputting them to a file it would take up gigabytes. what exactly do you want to do with the permutations? – David Coler Jan 10 '15 at 20:45
  • Its 10M to 20M. I lost one zero, but see OP. – laune Jan 10 '15 at 20:48
  • I found 10000000! = 1.202423401×10^65657059 – laune Jan 10 '15 at 20:51
  • Well, there are 10 million numbers in the range you are interested in. Each number has 40320 permutations. So, you are looking at 403.2 billion numbers. If you spend 1 millisecond to print out one number (in reality, it take longer), then it will take you about 13 years to print them all out. If additionally you spend 1 millisecond to produce one permutation, that'll take you another 13 years. How fast exactly do you need it to be? I mean, how old are you? – Dima Jan 10 '15 at 20:51
  • @Sdiao has to clarify if he/she wants permutations in range or permutations of 1 string only. Permuting numbers of 3 digits produces 3!, but permuting all numbers in 0-999 is 1000! There is a significance difference. – NoChance Jan 10 '15 at 21:00
  • Like everyone else, I'm not clear on what exactly you're looking for. However, the algorithm you've chosen may be the wrong one. You have 8 nested loops and each one runs 8 times, so the loop body will run 8^8 = 16777216 times. However, the number of permutations is 8! = 40320. That means you're doing about 416 times as much work as you should need to do. – ajb Jan 10 '15 at 22:51
  • @ajb you can skip inner loops by testing the outer loop counters. But the recursive algorithm (although not without overhead) is at least more elegant. – laune Jan 11 '15 at 06:52

2 Answers2

1

What about recursively, like they suggest over here?

Generating all permutations of a given string

Logic has been improved slightly due to Pham's suggestions. I think this is O(n) now... Let me know if someone sees differently.

import java.util.ArrayList;

    public class Main {

        static ArrayList<Integer> numbersList = new ArrayList<Integer>();
        static ArrayList<String> prefixList = new ArrayList<String>();

        public static void main(String[] args) {
            String number = "83241232";

            permutation(number);

            System.out.printf("Found %d unique permutations!%n", numbersList.size());
            for(int i=0; i<numbersList.size(); i++)
            {
                System.out.printf("%d%n", numbersList.get(i));
            }
        }

        public static void permutation(String str) { 
            permutation("", str); 
        }

        private static void permutation(String prefix, String str) {
            int n = str.length();
            if (n == 0) 
            {
                if(!prefixList.contains(prefix))
                {
                    prefixList.add(prefix);
                    numbersList.add(Integer.parseInt(prefix));
                }
            }
            else {
                for (int i = 0; i < n; i++)
                {
                    permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
                }
            }
        }
    }
Community
  • 1
  • 1
shutch
  • 197
  • 1
  • 1
  • 10
  • That should be a comment, not an answer. – laune Jan 10 '15 at 20:54
  • Well, he asked: "I want a program that takes in an 8 digits number and return all permutations of it." This program does that. I don't understand how this is not an answer to his question. Besides... you need 50 reputation to comment and I don't have that :/ Maybe you could up-vote my answer to help me get there? :P – shutch Jan 10 '15 at 21:01
  • This will return all permutations, with duplication, so it is not a correct answer, however, you can add small changes to make it correct! – Pham Trung Jan 11 '15 at 06:49
  • I added a check to remove the duplicates. I initially had no duplicates because my input string had no duplicates, but once I changed the string to have two identical digits, the duplicates were apparent. Thanks for pointing it out – shutch Jan 12 '15 at 01:59
  • 1
    This answer now is correct, but you just increase the total time complexity from O(n) to O(n^2)(n is number of permutation), which is not good. There is one better way, look at this line `permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));` you can check if the character `i` append to the `prefix` is already used before for example: prefix + 1 only need to be added once, if it is used before, you can skip this, this step will even reduce the time complexity for your program. – Pham Trung Jan 12 '15 at 06:16
  • I think I've added logic to improve run time to O(n) now. Please let me know if you think differently – shutch Jan 18 '15 at 23:03
0

for one too many loops this is a much easier example and this is just for a 10 digit array you can modify this to go through all 1000000 or how ever much you need it to, although it takes a while.

import java.util.Arrays;

/**
 *
 * @author David
 */
public class Permutations {

    /**
     * @param args the command line arguments
     */
    public static void permutations(int[] chararr,int start, int end)
    {
        System.out.println(Arrays.toString(chararr));
        if (start<end)
        {
            int i,j;
            for(i=end-2; i>=start; i--)
            {
                for(j=i+1; j<end; j++)
                {
                    Swap(chararr,i,j);
                    permutations(chararr,i+1,end);
                }
                Rotate_Left(chararr,i,end);
            }
        }
    }
    private static void Swap(int[] chararr,int i,int j)
    {
        int t;
        t = chararr[i];
        chararr[i] = chararr[j];
        chararr[j] = t;
    }

    private static void Rotate_Left(int[] chararr,int start,int end)
    {
        int tmp = chararr[start];
        for (int i=start; i < end-1; i++)
        {
            chararr[i] = chararr[i+1];
        }
        chararr[end-1] = tmp;
    }         

    public static void main(String[] args) {
        // TODO code application logic here
        int[] array = new int[10];
        for(int x = 0; x < array.length; x++)
            array[x] = x+1;
        permutations(array,0,array.length);

    }

}
David Coler
  • 453
  • 3
  • 8
  • Just a note this will give all valid permutations, however it does not check for duplicate numbers in the array, to get rid of dupes from the input is easy. – David Coler Jan 10 '15 at 21:01