简体   繁体   中英

Generate random numbers with different digits

How can I generate all numbers with different digits (PS they have to start and end with the first number of the array. For example, I have numbers 0 1 2 3 4 and I need to create numbers like 012340, 012430, 013240, 0124230.. If I have 5 numbers it means there are 24 different combinations(!(5-1)).

This is my code(its a little messy, but maybe someone can help me out). Maybe there could be a way to solve this with recursion?

    public void GenerateDigits(int n)
    {
        n--;
        int[] numbers = new int[n];

        for (int i = 0; i < n; i++)
        {
            numbers[i] = i;
        }

        string[] allDigits = new string[n*n];
        Random rnd = new Random();
        int counter = 0;
        while (allDigits.Length != counter)
        {
            allDigits[counter] = Convert.ToString(numbers[0]) + Convert.ToString(numbers[0]);

            while (allDigits[counter].Length != n + 1)
            {
                char skc = Convert.ToChar(rnd.Next(numbers[1], numbers[n]));
                if (!allDigits[counter].Contains(skc))
                {
                    allDigits[counter] = allDigits[counter].Insert(1,1);
                }
            }
        }
    }

OK as you correctly observed, there are (n-1)! distinct permutations of your array, and you want an algorithm that lists them in random order. If you need to produce the whole list in random order, I'd suggest generating the list of permutations first and then shuffling it. If you just want to generate these one at a time and don't mind duplicates, I'd recommend taking any fixed permutation, shuffling the digits that are eligible to change, and then outputting the result. These are both conceptually simple; use Fisher-Yates for shuffling.

Suppose instead what you want to do is to is to generate a sequence of permutations, all distinct, without first computing the list of all permutations. Such a list would be long for reasonable n. If the length of your sequence is small with respect to the number of permutations (n-1)!, then remembering which ones you have already generated and trying over and over again until you get one not in the list is a very feasible approach. You would need to work out the probabilities involved to give you a good idea of what "small" means for you (the expected runtime gets worse with each new permutation added to the list). If the number of permutations is known to be a sizable fraction of the number of all possible permutations, it's probably better to go ahead and calculate them all in advance, possibly in a compressed format to save space.

As you said "different digits", I asume it is a "unique results" kind of constraint (ie, 012340 only once). This is something that I call the "lottery problem".

If so the solution would be to create a collection with all possible permutations, then pick some of them at random with code similar this:

//Create an array. Fill it with Sequential Numbers.
int[] input = new int[20];

for(int i = 0; i < numbers.lenght; i++)
  input[i] = i;

/*Initialise the instances you will need*/
//Use the array to create a list
List<int> DrawableNumbers = new List<int>(input);
List<int> DrawnNumbers = new List<int>();

//Generate a Random Number Generator
Random rng = new Random();

/*Draw 6 from the group*/
while(DrawnNumbers.Count < 6){
  //Get a random Index to move from DrawableNumbers to DrawnNumbers
  int temp = Random.NextInt(DrawableNumbers.Count);
  DrawnNumbers.Add(DrawableNumbers[i]);
  DrawableNumbers.Remove(temp);
}

As the number of Permutations is non-linear and might require pretty big integers down the line (or even storing the values as strings), as a advanced version you could just number the possible combinations. ie 1234 is 1, 1243 is 2, etc. And then generate the actually result for output as late as possible.

Treating the digits that bracket the sequence (the index 0 digit) as a seperate thing - possibly a own field in a custom class - might help with that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM