2

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();
}
2
  • 1
    Possible duplicate of Randomize a List<T> Commented Oct 23, 2017 at 5:53
  • 1
    What's the idea behind of this code? Do you want to zero file starting from random position [1, 1024*2000-1] ? Commented Oct 23, 2017 at 6:31

6 Answers 6

4

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);
Sign up to request clarification or add additional context in comments.

1 Comment

Probably better to use a HashSet<int> since you only need the "keys"
2

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();
}

5 Comments

Lookup in List is O(n). Might be pretty slow solution in some scenario
@artavazd I agree, have you got any better option apart from using GUIDs?
HashSet and Dictionary has O(1) for lookup, SortedSet has O(logn)
O(n) when n is 100 -- as in the question -- can pretty much be ignored.
this indeed is not guaranteed to finis, and list lookup might be very expensive even for moderate sizes.
1

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

Comments

1

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.

Comments

1

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;
        }
    }
}

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.