0

i'm trying to get X number of random number (where X is a variable) between 0 and 100 and add them to a row in a DataGridView. I'm using the code below, but the problem is i need it to be impossible to have the same number twice. Is there a way make sure i get unique random numbers?

int X = 20;
Random random = new Random();
int randomrow = random.Next(0, 100);

for (int i = 0; i < X; i++)
{
   int randomNumber = random.Next(0, 100);
   data.Rows[randomrow][3] = randomNumber;
}

Thanks for the help!

Davevmb
  • 85
  • 1
  • 11
  • 1
    use a List to hold your random values. when you generate a new one check if it exists in that list and generate a new one if it does, then add them all to the DataGridView – Marco Fatica Nov 04 '15 at 16:56
  • Do you want `randomrow` to be unique? Or `randomNumber`? – Matias Cicero Nov 04 '15 at 16:56
  • 2
    Possible duplicate of [Generating random, unique values C#](http://stackoverflow.com/questions/14473321/generating-random-unique-values-c-sharp) – FabioG Nov 04 '15 at 16:58
  • If you want a true random value, you need to use something other than the `Random` class. [`Random` is only psuedo-random](https://en.wikipedia.org/wiki/Pseudorandomness). In order to generate real ones, you can use something like `RNGCryptoServiceProvider`. – Ron Beyer Nov 04 '15 at 16:59
  • Why does randomrow never change? You are updating the same row x times. – John Paul Nov 04 '15 at 17:18
  • What happens if x is 101? – Eric Lippert Nov 04 '15 at 19:08
  • Note that the second argument to [`Random.Next`](https://msdn.microsoft.com/en-us/library/2dx6wyd4(v=vs.110).aspx) is the *exclusive* upper bound. `Random.Next(0, 100)` returns a random integer between 0 and 99, and will never return 100. – drf Nov 04 '15 at 23:29

4 Answers4

6

Split your problem in two:

  1. Create a list of X random, unique numbers. There are numerous ways to do that:

    a. Create a list of all numbers 0-100 and then shuffle them. OR

    b. Keep a hash set of all the numbers you already created (in addition to the list) and only add a new one if it has not been added before.

  2. Afterwards, loop through the list and the data rows simultaneously and insert the values into the rows.

Community
  • 1
  • 1
Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • The list should be a [HashSet](https://msdn.microsoft.com/es-es/library/bb359438(v=vs.110).aspx) – Matias Cicero Nov 04 '15 at 16:57
  • 2
    @MatiasCicero: I don't think so: A hashset has no defined order, so shuffling is not possible. – Heinzi Nov 04 '15 at 16:58
  • 5
    Making a list of 0 to 100 won't have duplicates either, and then shuffling is O(n) basically. This is a lot better than generating random unique numbers, redoing all the ones that already existed, while having more and more already existing numbers as you go. – SimpleVar Nov 04 '15 at 16:59
  • @YoryeNathan Oh I understand now, my bad! – Matias Cicero Nov 04 '15 at 17:00
  • 1
    @MatiasCicero: But your suggestion of using a hash set is good *if* the OP sticks to his original algorithm. I've added that option. – Heinzi Nov 04 '15 at 17:00
0

You would need to compare the numbers you have already used to the next one you get from random.Next. If you have already used it, pick another. I also like Heinzi's answer.

Dave_750
  • 1,225
  • 1
  • 13
  • 28
0

Here's the simple way to do it without creating a shuffle method for the List (though there are examples of that). Basically create a list of all possible integers, populate the list, then sort by new GUIDs.

        int X = 20;
        var RowNumbers = new List<int>();

        for (int i = 0; i < X; i++)
            RowNumbers.Add(i);

        foreach (int i in RowNumbers.OrderBy(f => Guid.NewGuid()))
        {
            data.Rows[i][3] = i;
        }
0

Here is algorithm without shuffling and previous result using:

var max = 100; // max available value
var count = 20; // number of random numbers

var random = new Random();
var rest = (double)max;
for (int i = 0; i < max; i++, rest--)
{
    if (count / rest > random.NextDouble())
    {
        Console.WriteLine(i); // here is your random value
        count--;

        if (count == 0)
        {
            break;
        }
    }
}
Alexander
  • 560
  • 3
  • 14