0

I need some help to do my homework. I should write non-duplicate random numbers. I'm able to show random numbers but I don't know about non-duplicate.

Here's my code:

Random r = new Random();
for (int i = 0; i < 40; i++)
{
    int temp = r.Next(0, 100);
    Console.WriteLine(temp);
}

What do I need to do to generate non-duplicate number?

  • You should built a list of numbers 0-99 in order, and then shuffle them. See [this question](https://stackoverflow.com/questions/273313/randomize-a-listt) – ProgrammingLlama Oct 23 '19 at 01:07
  • i just so little to understand this i am new :( can i want from you to complete this part for me plz? :( –  Oct 23 '19 at 01:13
  • the only way you can do this is to create a list of the numbers you already generated, then when you generate a new one, see if it is in that list already and if it is, create a new one. You can do this is a do loop (do until not in result set). – John Lord Oct 23 '19 at 03:12

2 Answers2

3

Note that this answer only deals with (relatively) small, pre-determined sets.

The reason the other (simple) solution is inefficient is this: you want to generate 100 random numbers between 0 and 99. You get to the point where you have generated 90 random numbers, and just need 10 more.

The problem is that you're still generating numbers between 0 and 99 every time, except now your chance of finding a number that hasn't already been generated is 1 in 10. So 9 of every 10 numbers you generate has already been added to the list.

Once you get down to just needing 1 number, your chance of generating the remaining 1 that hasn't already been generated is 1 in 100. So for every 100 numbers you generate, only 1 of them will be the last possible number.

I'm sure this is simplifying things given that the Random class is pseudo-random (i.e. it's an algorithm that appears random), but this does explain your situation and why the other answer will be slower.

An improved solution would be this:

// Add all of the numbers 0 to 100 to a list
var availableNumbers = new List<int>();
for (int i = 0; i < 100; ++i)
{
    availableNumbers.Add(i);
}

Random random = new Random();
for (int i = 0; i < 40; ++i)
{
    // Choose a random position in the available numbers list
    var idx = random.Next(0, availableNumbers.Count);

    // Print the number from this position in the list
    Console.WriteLine(availableNumbers[idx]);

    // Remove the item at this position
    availableNumbers.RemoveAt(idx);
}

Because we start with a list of all available numbers, we are able to choose numbers from it at random. Removing items from the available numbers list means that they are not available to be chosen a second time. We no longer have to try many times to find an unused number, as removing them when we select them ensures that all of the numbers in the available numbers list are always only unused numbers.

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
  • To anyone reading: I'm aware that I could write this in a single line with LINQ, but I don't think that would be particularly helpful to OP's learning. – ProgrammingLlama Oct 23 '19 at 02:05
  • ooh that's so huge , this one is no limited of value , thank you for learn this to me –  Oct 23 '19 at 02:21
1

You may use a HashSet to store the numbers and make sure there are no duplicates. Here's an example:

HashSet<int> numbers = new HashSet<int>();
Random r = new Random();
for (int i = 0; i < 40; i++)
{
    int temp;
    do
    {
        temp = r.Next(0, 100);
    } while (numbers.Add(temp) == false);   // If the `.Add()` method returns false,
                                            // that means the number already exists.
                                            // So, we try to generate another number.
    Console.WriteLine(temp);
}
  • do you have better idea about it? –  Oct 23 '19 at 01:38
  • @TheGeneral There are obviously better algorithms for generating random numbers without repetition but a) what's a more efficient one that you'd present to an absolute beginner (according to the OP)? b) Is it actually _very_ inefficient (especially for a collection with only 40 items)? – 41686d6564 stands w. Palestine Oct 23 '19 at 01:41
  • it's just for practicing , non-duplicate numbers of 40 three-digit numbers in an array , That's what my teacher said , What is the principle code for this question? –  Oct 23 '19 at 01:50
  • @MR.JAWEED If you want to convert it to an array, you may use something like `int[] myArray = numbers.ToArray();` at the end. – 41686d6564 stands w. Palestine Oct 23 '19 at 01:53
  • you could also forget the hashset. Dim an int array of length 40 and populate that directly, which checking all previous entries for matches. They don't teach you hash sets in beginner class and this will probably make the teacher suspect you're cheating. – John Lord Oct 23 '19 at 03:16