C # random number generator - unique values

I am busy in C # with array encoding. I can fill it with random generators, but now my question is how to do it, but so that I can check if this value is already in the array, and if so it generates a new value

Additional Information:
Maximum value: 100
Number of items: 100

IMPORTANT PLZ WORK NEXT ON MY IDEA

my idea

public void FillArray(int[] A, int Range) { for (int I = 0; I < A.Length; I++) { A[I] = ValidNumber(T, I, Range); } } /* Fill Array */ 

Implementing sorting sorting

 public void SelectionSort(int[] A) { int K, X; for (int I = 0; I < A.Length - 1; I++) { K = I; X = A[K]; for (int J = I + 1; J < A.Length; J++) { if (A[J] < X) { K = J; X = A[K]; } } A[K] = A[I]; A[I] = X; } } /* Selection sort */ 

These are just some ideas, now I want to know how I can fix it, so I can look with a selection of sorting if there is allread there (fillarray), that is, if it replaces it with a new random value. And so I want to create a random array with ints - from 1 to 100 in random order

+7
arrays c # random
source share
5 answers

how to do it, but so that I can check if this value is already in the array, and if so it generates a new value

You do not do it because it is a very bad idea.

To illustrate why this is a terrible idea, consider another version of the same problem: collect a million numbers in random order by the following process:

  • Choose a number from one to a million.
  • Check if there is any in the list.
  • If so, return to step 1
  • Otherwise, add the number to the list.
  • Is there one million items in the list? If yes, then everything is ready. If not, return to step 1.

Clearly this works. Is that a good idea? Suppose you are almost done. There are 999999 items in the list. The only missing element is 857313. What are you doing? You pick a random number, say 12. Now you check the elements 999999 in the list to see if any of them are 12. 12 may have been one of the first numbers you selected, so you could quickly find it . Or it may be one of the last, so it will take a long time. An average of 500,000 checks will show if there are 12 in the list. And this is so, since there is only one number in the list.

12 failed. Go back to the beginning. Choose another random number, say 53259. Is it on the list? Another half a million checks.

Keep doing this until you generate 857313, which happens once in a million attempts.

So, on average, 500,000 x 1,000,000 = five hundred billion comparisons are required to place the last item on the list. It can go even further. This may take several trillion comparisons. Or you are lucky and it will take one. But an average of half a trillion comparisons.

This is a terrible way to create a random list order.

There are two good ways to do a random list order.

(1) Create a device that can sort the list with the specified order function. Provide a stable ordering based on random seed.

Note that you should not create random order by creating a method that returns random results when asked: "Is A greater than B?" This is an erratic ordering; many sorting algorithms are based on stable sorting ordering and will go into infinite loops or have other bad behavior when specifying unstable sorting ordering.

This algorithm is O (n lg n) and has a nice property that is very easy to write from the standard parts, as other answers indicate. It is also extremely fast for small lists in typical implementations.

(2) Select an item by index from a list of sources in a random order, removing it from the source list in the process and placing it in the address list.

The latter is known as Knuth Shuffle or Fischer-Yates Shuffle, and it is a very fast algorithm. You can do this "in place" by mutating the existing array into shuffled order or by creating a new list. It also has a good property that you can "pay for the game" by shuffling the "top" of the list when you need it. If you have a million items to shuffle, but you only need the first hundred, you can simply develop a sort order for the first hundred and call it good.

+30
source share

Next, an array with the numbers 1-100 will be created in random order.

  Random rnd = new Random(); var randomNumbers = Enumerable.Range(1, 100).OrderBy(i => rnd.Next()).ToArray(); 
+6
source share

From your description, I take that you need an array of 100 integers with values ​​from 1 to 100 and without duplicate numbers. If the numbers are integers, you do not need to generate random numbers, since all possible numbers are in the array. Thus, only the order or numbers can be randomized.

Using the Linq and Jesper Palm approach - with Thomas Levesque, the following statement will give you the array you need.

 Random rnd = new Random(); var randomNumbers = Enumerable.Range(1, 100) .Select(x => new { val = x, order = rnd.Next() }) .OrderBy(i => i.order) .Select(x => x.val) .ToArray(); 

The method is even quite fast, definitely more efficient than any comparison operation.

To explain the above on the original poster, see the comment below:

  • Enumerable.Range(1, 100) creates a range of integers starting at 1 and ending at 100.
  • .Select(x => new { val = x, order = rnd.Next() }) creates a new temporary object that holds the value and order position, which is determined by a random number.
  • .OrderBy(i => i.order) sorts temporary objects by its order position.
  • .Select(x => x.val) selects the value of a temporary object, converting it back to int.
  • .ToArray() returns to the array again.

The syntax used is LINQ, which is available in .NET 3.5. With the older versions that you use, you need to implement this yourself, which is much more complicated and quite a long time.

Follow Eric's comment: If reordering, you can make the code as follows

 var list = myInputList; var result = list.Select(x => new { val = x, order = rnd.Next() }) .OrderBy(i => i.order) .Select(x => x.val) .ToArray(); 
+5
source share

Here's a naive implementation:

 int[] values = new int[100]; Random random = new Random(); for(int i = 0; i < values.Length; i++) { int v; do { v = random.Next(100) + 1; } while (Array.IndexOf(values, v) != -1) values[i] = v; } 

But that would be pretty inefficient, especially near the end of the array ...

The best solution would be to consider this, since you want 100 different values ​​from 1 to 100 in random order, your array will eventually contain all possible values ​​from 1 to 100. So you just need to create a sequence of these values ​​and "to shuffle":

 int[] values = Enumerable.Range(1, 100).ToArray(); Random random = new Random(); for(int i = values.Length - 1; i > 0; i--) { int j = random.Next(i + 1); int tmp = values[i]; values[i] = values[j]; values[j] = tmp; } 

EDIT: A better approach that should work for less specific cases:

 T[] RandomCombinationWithNoRepeat<T>(IEnumerable<T> itemsToPickFrom, int numberOfItemsToPick) { // Copy original items to pick from, because we need to modify it List<T> itemsCopy = new List<T>(itemsToPickFrom); T[] array = new T[numberOfItemsToPick]; Random random = new Random(); for(int i = 0; i < numberOfItemsToPick; i++) { // Pick item and remove it from list int index = random.Next(itemsCopy.Count); array[i] = itemsCopy[index]; itemsCopy.RemoveAt(index); } return array; } 

In your case, you will use it like this:

 int[] result = RandomCombinationWithNoRepeat(Enumerable.Range(1, 100), 100); 
+2
source share

from what I understood. You will need a set of integers with random numbers. I assume that using an int array or List of int does not matter. Here is a simple complete approach that you described.
using System; using System.Collections.Generic; using System.Text;

namespace FillRandom {class Program {static void Main (string [] args) {int minValue = 1; int maxValue = 100; // create a list of int with capacity set as 100 List array = new List (100);

  FillArray(array, minValue, maxValue, array.Capacity); //print out all values in the array foreach (int i in array) { Console.WriteLine(i); } } private static void FillArray(List<int> array, int minValue, int maxValue, int capacity) { int count = 0; while (array.Count != capacity - 1) { Random rnd = new Random(); int value = rnd.Next(minValue, maxValue); if (!array.Contains(value)) { array.Add(value); } count++; } //print out the number of times the looping occurs Console.WriteLine("count: "+count); } } 

} Code>

You can create a console project and try.

0
source share

All Articles