Reputation: 11319
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
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
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
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
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
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
Reputation: 236
It's simple. Just write each number while generation. Then check that new number is not equal to generated.
Upvotes: 1