Daniel Lip
Daniel Lip

Reputation: 11319

How can i generate random numbers without repeating/duplicate the same number?

What i want it to do is to generate 100 files each file with a different random size. If the line:

long rndsize = rnd.Next(1, 2000);

Generated the number 43 then don't generate this number again.

In the constructor:

CreateFiles(100);

And the method:

for (int i = 0; i < numberoffiles; i++)
{
    Random rnd = new Random();
    long rndsize = rnd.Next(1, 2000);
    FileStream fs = new FileStream(@"c:\temp\files\huge_dummy_file" + i, FileMode.CreateNew);
    fs.Seek(rndsize * 1024, SeekOrigin.Begin);
    fs.WriteByte(0);
    fs.Close();
}

Upvotes: 2

Views: 5029

Answers (6)

Aarsh
Aarsh

Reputation: 2595

You can use guid as well. It generates a different number each time. This is inbuilt functionality in asp.net. It is far better than doing it by making a function to generate a random number.

Upvotes: 0

Blue Granny
Blue Granny

Reputation: 800

Add a hashset, and when you rand a number check if it exists. If it does rand another number. You're only generating 100 files so in the last iteration you'll have to rand approx 20 numbers but that shouldn't take too long.

So add HashSet<int> existingNumbers = new HashSet<int>();

And instead of long rndsize = rnd.Next(1, 2000);

Do:

int rndsize;
do {
  rndsize = rnd.Next(1, 2000);
} while (existingNumbers.Contains(rndsize));
existingNumbers.Add(rndsize);

Upvotes: 4

Artavazd Balayan
Artavazd Balayan

Reputation: 2413

To avoid duplicates, you have to check that number has been generated. For fast lookup you can use HashSet. This is pretty dummy solution - to avoid infinite loop there is limitation on the number of iterations.

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var rnd = new Random();
        var rndGen = new UniqueRandomGenerator(rnd);

        Console.WriteLine("Next random values from 1 to 5:");
        for (int i = 1; i <= 5; i++) {
            var next = rndGen.GetNext(1, 6);
            Console.WriteLine(next);
        }
    }

    class UniqueRandomGenerator
    {
        readonly Random _rnd;
        readonly HashSet<int> _generated;
        readonly static int MAX_ITER_WHILE_GET_NEXT_RND = 100;

        public UniqueRandomGenerator(Random rnd) 
        {
            _rnd = rnd;
            _generated = new HashSet<int>();

        }

        public int GetNext(int lower, int upper) {
            int next;
            int i = 0;
            do {
                next = _rnd.Next(lower, upper);
                i++;
                if (i > MAX_ITER_WHILE_GET_NEXT_RND)
                    throw new InvalidOperationException("Exceed iter limit!");
            }
            while (_generated.Contains(next));
            _generated.Add(next);
            return next;
        }
    }
}

Upvotes: 1

Ian H.
Ian H.

Reputation: 3919

To add on to the existing answers:

The reason why you are getting the same results is that you are creating a new instance of the Random class every loop iteration.

This class uses a seed to generate pseudo-random numbers, which is initially calculated using the current tick count of DateTime.Now. This seed is changed after requesting a new random integer, preparing for the next random number.

If you generate a new instance every iteration, the instances will most likely have the same seed, which will lead to them producing the same results.

Upvotes: 1

Ipsit Gaur
Ipsit Gaur

Reputation: 2927

First of make only one instance of Random, and then use a list to store all generated numbers and check it before creating files with the newly generated number

Random rnd = new Random();
List<long> generatedNumbers = new List<long>();
for (int i = 0; i < numberoffiles; i++)
{
    long rndsize = rnd.Next(1, 2000);
    if(generatedNumbers.Contains(rndSize)) 
    {
      i--;
      continue;
    }

    generatedNumbers.Add(rndSize);
    FileStream fs = new FileStream(@"c:\temp\files\huge_dummy_file" + i, FileMode.CreateNew);
    fs.Seek(rndsize * 1024, SeekOrigin.Begin);
    fs.WriteByte(0);
    fs.Close();
}

Upvotes: 2

Lil Bro
Lil Bro

Reputation: 236

It's simple. Just write each number while generation. Then check that new number is not equal to generated.

Upvotes: 1

Related Questions