3

When using the random utility in java, you get some numbers like this: 1271, 34556, 177, etc... What is the simplest way to make it so the digits don't repeat?

Ivan Doronin
  • 86
  • 1
  • 6

6 Answers6

9

You could shuffle the array [1,2,3,4,5,6,7,8,9] and read that as a number.

If you don't want to fix the number of digits, or allow a non-leading zero, it gets more complicated (if you care about some sort of equal distribution).

Thilo
  • 257,207
  • 101
  • 511
  • 656
6

You could initialize a List with the digits 0-9. Then randomize this list and poll a random amount of elements (between 1 and 9) from this list. Concatenate the digits and you have your number with non-repeating digits.

Michael Lang
  • 3,902
  • 1
  • 23
  • 37
  • 3
    Random amount of elements is tricky. If you use a naive distribution, you will have much more short numbers than you may want to get (less than 10% of all numbers with up to ten digits have only one digit, but you might end up with 10%). – Thilo Jul 15 '13 at 09:52
3

How about creating a loop that checks if the generated random number meets your requirements.

final Random rnd = new Random();
int n;
do {
    n = rnd.nextInt(1000);
} while(containsRepeatingDigits(n));

containsRepeatingDigits can look like this:

boolean containsRepeatingDigits(final int n) {
    final boolean digits[] = new boolean[10];
    for(char c : String.valueOf(n).toCharArray()) {
        final int i = c-'0';
        if(digits[i])
            return true;
        digits[i] = true;
    }
    return false;
}
Adam Siemion
  • 15,569
  • 7
  • 58
  • 92
1

You could check if the random number has repeating digits and generate a new one if it does. It's written in C#, but you should be able to convert this to Java real easy.

    private static Random rand = new Random();
    public static int GenerateNumberNonRepeat()
    {
        int number;
        do
        {
            number = rand.Next();
        } while (IsRepeating(number));

        return number;
    }

    public static bool IsRepeating(int number)
    {
        string textual = number.ToString();
        for (int i = 0; i < textual.Length; i++)
        {
            for (int j = i + 1; j < textual.Length; j++)
            {
                if (textual[i] == textual[j])
                    return true;
            }
        }

        return false;
    }
MrFox
  • 4,852
  • 7
  • 45
  • 81
  • This is the easiest way to get an even distribution. It might get a little slow for big numbers, however. Say you want a random number smaller than `10^10`, then about `90%` of the numbers is invalid. – Vincent van der Weele Jul 15 '13 at 09:59
0

Another way to generate those numbers is to generate arbitrary number, and in case that it contains repeating digits either generate a new one, or remove the repeating digits (by e.g. increment the number until there are no more repeating numbers).

In contrast to proposed shuffle/select approach this has the advantage, that you keep (more or less) the distribution of the original rng.

flolo
  • 15,148
  • 4
  • 32
  • 57
0

This code may help you

    Set set  = new HashSet<Integer>();
    Random rand= new Random();
    public int getNonRepeatingRandomNumber() {
        int intV = rand.nextInt();
        if(set.contains(intV)) {
            return getNonRepeatingRandomNumber();
        }
        else {
            set.add(intV);
            return intV;
        }
    }
vels4j
  • 11,208
  • 5
  • 38
  • 63