Unique random number

To generate random numbers from 1-20, I need to select a sample and should not be repeated.

How to do it in C #

Note. I need to run a loop like this.

Random rnd = new Random() rnd.Next(1,20) for(int i =0; i<=20;i++) { } 

For all numbers of cycles should be from 1 to 20

+6
c # random
source share
9 answers

What exactly do you mean by "should not be repeated"? If you mean that you do not want to receive any duplicates, then you should basically take a list of numbers 1-20, shuffle them, and then grab one from the list header. For effective shuffling of a list, see this answer .

If you just mean that your current attempt gives 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, and etc. then, most likely, you create a new instance of Random every time you select a number: do not do this. Each time you create an instance, it will use the current time as a "seed" for a random number generator (unless you specify it explicitly). This means that if you create multiple instances in quick succession, each will receive the same seed and therefore will give the same sequence of numbers.

Instead, use one instance of Random and reuse it. (Note that this is not thread safe, although it is a pain.) For example:

 private static readonly Random Rng = new Random(); public int NextNumber() { return Rng.Next(20) + 1; } 

This will not be thread safe, but let us know if this is a problem. An alternative is sometimes to pass Random to a method (which, of course, will, of course, be more complicated, of course):

 public int NextNumber(Random rng) { return rng.Next(20) + 1; } 

then the caller can reuse the instance accordingly.

If you need a thread-safe way to generate random numbers, you can look at my StaticRandom class in MiscUtil .

(Note that using rng.Next(1, 21) will also work fine - I prefer the version above, since I think it reduces the guesswork about inclusive / exclusive borders, but this is a matter of personal taste.)

+21
source share

This method will generate all numbers and the numbers will not be repeated:

 /// <summary> /// Returns all numbers, between min and max inclusive, once in a random sequence. /// </summary> IEnumerable<int> UniqueRandom(int minInclusive, int maxInclusive) { List<int> candidates = new List<int>(); for (int i = minInclusive; i <= maxInclusive; i++) { candidates.Add(i); } Random rnd = new Random(); while (candidates.Count > 0) { int index = rnd.Next(candidates.Count); yield return candidates[index]; candidates.RemoveAt(index); } } 

You can use it as follows:

 Console.WriteLine("All numbers between 0 and 20 in random order:"); foreach (int i in UniqueRandom(0, 20)) { Console.WriteLine(i); } 
+17
source share

An IEnumerable implementation based on Hallgrim's answer :

 public class UniqueRandoms : IEnumerable<int> { Random _rand = new Random(); List<int> _candidates; public UniqueRandoms(int maxInclusive) : this(1, maxInclusive) { } public UniqueRandoms(int minInclusive, int maxInclusive) { _candidates = Enumerable.Range(minInclusive, maxInclusive - minInclusive + 1).ToList(); } public IEnumerator<int> GetEnumerator() { while (_candidates.Count > 0) { int index = _rand.Next(_candidates.Count); yield return _candidates[index]; _candidates.RemoveAt(index); } } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } } 
+2
source share

I did it so a little back. I do not know how this compares with other methods presented in terms of efficiency, randomness, etc. But it seems to work:

 List<int> integers = new List<int>() { 1, 2, 3, 4, 5, 6,7, 8, 9, 10, 11, 12 }; Random rnd = new Random(); var ints = from i in integers orderby rnd.Next(integers.Count) select i; 
+1
source share

From MSDN

"One way to improve randomness is to make a temporary value of the initial value."

Another fact

you should "create one Random to generate many random numbers over time." It will improve random generation.

0
source share
 class Program { static void Main(string[] args) { List<int> list = new List<int>(); int val; Random r; int IntialCount = 1; int count = 7 ; int maxRandomValue = 8; while (IntialCount <= count) { r = new Random(); val = r.Next(maxRandomValue); if (!list.Contains(val)) { list.Add(val); IntialCount++; } } } } 
0
source share

The following method is very good, I use the line here, you can change the list type to whatever you want ... try:

  List<string> NamesList = new List<string>() { "Name1", "Name2", "Name3", "Name4", "Name5" }; Random rnd = new Random(); //Now to get random of the above "Without Repeating.." for (int i = 0; i <= NamesList.Count - 1; i++) { int TheSelectedRand = rnd.Next(NamesList.Count); string MyRandNumber = NamesList[TheSelectedRand]; //Print or use your item here NamesList.Remove(NamesList[TheSelectedRand]); } 
0
source share

The binary code generates 65 unique random numbers between 0 - 92 and returns this unique random numbers in the array.

 public static int[] RandomNumbers_Supplier() { Random R = new Random(); int[] RandomNumbers = new int[65]; int k = 0, Temp; bool IsRepetitive = false; while (k < 65) { Temp = R.Next(0, 92); for (int i = 0; i < 65; i++) { IsRepetitive = false; if (RandomNumbers[i] == Temp) { IsRepetitive = true; break; } } if (!IsRepetitive) { RandomNumbers[k] = Temp; k++; } } return(RandomNumbers) } 
-one
source share
 static void Main(string[] args) { //Randomize 15 numbers out of 25 - from 1 to 25 - in ascending order var randomNumbers = new List<int>(); var randomGenerator = new Random(); int initialCount = 1; for (int i = 1; i <= 15; i++) { while (initialCount <= 15) { int num = randomGenerator.Next(1, 26); if (!randomNumbers.Contains(num)) { randomNumbers.Add(num); initialCount++; } } } randomNumbers.Sort(); randomNumbers.ForEach(x => Console.WriteLine(x)); } 
-one
source share

All Articles