-1

I have a little problem. I want fill my array with 100 random numbers. The problem is i have a lot of the same numbers 2/4 of my array is 0 then 1/4 89 andso how is this possible ???

thanks for helping

public void arrayreverse()
{
    int[] arr = new int[100];
    Random r = new Random();

    for (int i = 0; i < 100; i++)
    {
        int rand = r.Next(0, 100);
        arr[i] = rand;
        Array.Sort(arr);
        Array.Reverse(arr);
        Console.WriteLine(arr[i]);
    }
    Console.ReadLine();
}
Arghya C
  • 9,805
  • 2
  • 47
  • 66
Feren
  • 61
  • 2
  • 7
  • 1
    You sort the array *inside* the loop. That's the bug. – President James K. Polk Oct 09 '15 at 17:07
  • I agree with @JamesKPolk. You are overwriting entries because of the sorting that you perform on each iteration. – Lorek Oct 09 '15 at 17:09
  • While the sorting would cause performance issues it doesn't get to the fact that Random doesn't work well in tight loops. It is mostly based on computer time so values create in tight loops have a high likely hood of having repeat values. – Matthew Whited Oct 09 '15 at 17:13
  • This is mathematically interesting for me. – SimpleVar Oct 09 '15 at 17:15
  • https://en.wikipedia.org/wiki/Pseudorandom_number_generator – Matthew Whited Oct 09 '15 at 17:15
  • If you want a "better" random in C# (or other .Net languages) use this ... https://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider(v=vs.110).aspx – Matthew Whited Oct 09 '15 at 17:17
  • 1
    You are not getting as many duplicates as you think you are. You are dumping the index after you sort and reverse your data. you will always print the lowest value in the array the way it is coded. – tdbeckett Oct 09 '15 at 17:30
  • @MatthewWhited "Random doesn't work well in tight loops"??? I don't see any reason for that statement - the `Random` implementation is well defined piece of code and does not use any external inputs except possible initial seed to generate next number. I don't see how using loop vs. not using one would change that behavior. – Alexei Levenkov Oct 09 '15 at 18:30
  • Random is based on a time based seed. Computers are so fast not they can end up using the same seed with and give you the same result between calls. Don't trust me word go try it. – Matthew Whited Oct 09 '15 at 18:38
  • @MatthewWhited: That's not the problem. The random number generator is only seeded once. – recursive Oct 09 '15 at 19:56
  • The seed is used on every call. Again try it. – Matthew Whited Oct 09 '15 at 20:06
  • I was simply starting why OP was seeing so many duplicate "random" values. if you want a better random you could `Thread.Sleep(300)` on each loop or better still use the cryptographic random generator. – Matthew Whited Oct 09 '15 at 20:11
  • @MatthewWhited I suspect you are talking about different code when random *created* inside the loop (as shown in http://stackoverflow.com/questions/767999/random-number-generator-only-generating-one-random-number), not the code OP provided (where `Random` created outside the loop, and presumably placed inside the function to provide [MCVE]). – Alexei Levenkov Oct 09 '15 at 21:26

4 Answers4

3

Since you sort and reverse the array inside the loop you basically force the biggest number to be last.

For example in 5 sized array:

i = 0
arr[i] = rand:
arr -> 5 0 0 0 0

sort and reverse
arr -> 5 0 0 0 0
output = 5

i = 1
arr[i] = rand:
arr -> 5 8 0 0 0

sort and reverse
arr -> 8 5 0 0 0
output = 5

i = 2
arr[i] = rand:
arr -> 8 5 7 0 0

sort and reverse
arr -> 8 7 5 0 0
output = 5

i = 3
arr[i] = rand:
arr -> 8 5 7 2 0

sort and reverse
arr -> 8 7 5 2 0
output = 2

i = 4
arr[i] = rand:
arr -> 8 7 5 2 0

sort and reverse
arr -> 8 7 5 2 0
output = 2

As you can see, your output will always be the smallest number and as you go on, less and less number generated by the Random.Next can be smaller than the current smallest so the current smallest will most likely appear again as the output.

If you want to make a list of 100 numbers and print them you can use this Linq:

(new int[100])
    .Select(x => r.Next(100))
    .ToList()
    .ForEach(x => Console.WriteLine(x));

If you want the numbers to be distinct (all the numbers between 0 and 99 but you want them to appear only once) you can use the following code:

private static Random r = new Random();

public static int[] GetRandomArray(int size)
{
    SortedDictionary<double, int> sortedSet = new SortedDictionary<double, int>();
    for (int index = 0; index < size; index++)
    {               
        sortedSet.Add(r.NextDouble(), index);
    }
    return sortedSet.Select(x => x.Value).ToArray();
}
Tamir Vered
  • 10,187
  • 5
  • 45
  • 57
2

LINQ is easier to get right:

var randomNumbers = 
      Enumerable.Range(0, 100) // create sequence of 100 elements
      .Select(_ =>r.Next(0,100)) // for each element select random value
      .ToArray(); // convert to array.

As for your current sample - move sorting out of the for loop to fix bug.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
2

"Random" doesn't imply unique. You can still achieve the expected behavior by using a set:

    var takenNumbers = new SortedSet<int>();

    while (takenNumbers.Count != 100)
    {
        takenNumbers.Add(r.Next(0, 100));
    }

    var array = takenNumbers.ToArray();

It seams, however, that you want to build a unique sequence , not a set.

Here is code building a sequence:

    var takenNumbers = new HashSet<int>();

    var array = int[100];
    while (takenNumbers.Count != 100)
    {
        int rand = r.Next(0, 100);
        if (takenNumbers.Add(rand))
        {
           array[takenNumbers.Count - 1] = rand; 
        }
    }

    foreach(var number in arr)
    {
       Console.WriteLine(number);
    }
alexm
  • 6,854
  • 20
  • 24
0
public void Arrayreverse()
{
    int[] arr = new int[100];
    Random r = new Random();

    for (int i = 0; i < 100; i++)
    {
        int rand = r.Next(0, 100);
        arr[i] = rand;
    }

    Array.Sort(arr);
    Array.Reverse(arr);

    for (int i = 0; i < 100; i++)
    {
        Console.WriteLine(arr[i]);
    }
    Console.ReadKey();
}
kame
  • 20,848
  • 33
  • 104
  • 159
  • running that you get duplicates comment out the `Array.Sort(arr) && the Array.Reverse(arr)` you will see that you will get random numbers however there will be some duplicate numbers but not as many as there were with all the Sorting and Reverse code.. – MethodMan Oct 09 '15 at 17:18
  • I thougt he want duplicates? – kame Oct 09 '15 at 17:20
  • perhaps you need to read the question again the OP Clearly states the following `I want fill my array with 100 random numbers. The problem is i have a lot of the same numbers` – MethodMan Oct 09 '15 at 17:23
  • If you want random numbers, there are almost same numbers. But Feren said, that he has about 50% Zeros, what is strange. – kame Oct 09 '15 at 17:32
  • remove the 2 lines from your code you posted run the code and you will see the difference.. your code is not going to yield the proper results.. – MethodMan Oct 09 '15 at 17:34
  • @kame: It's not 50% zeroes. The code always prints the lowest number found so far. – recursive Oct 09 '15 at 17:36
  • But Feren seems to want an sorted array in the end, right? – kame Oct 09 '15 at 17:40
  • 1
    @recursive I think it is 50% zeros BECAUSE the code alway prints the lowest number found so far. – kame Oct 09 '15 at 17:42
  • 1
    @kame: Yes, that's what I'm trying to say. That means it's not strange to be 50% zeroes. That's what one would expect. – recursive Oct 09 '15 at 18:36