How to create an array of non repeating random num

2019-01-28 06:36发布

I have a lottery application in C# which takes in the number of numbers to draw and also the maximum number to draw.I have coded up to creating an array holding the required random numbers but I need them to be unique and am having trouble doing it.I would be very grateful if someone could give me some advice on this,Thanks

Here is my code so far:

class Lottery

{

  static int[] numberHolder; //array to be filled with numbers up to an 
                             //amount entered by the user eg 42 Max

  static int[] drawHolder;   //array to hold the each random number 
                             //drawn from the pool of numbers eg 7 numbers

    public Lottery() //Lottery class Constructor
    {

    }


    //method which takes in a number limit and amount of numbers to be drawn
    public String drawNumbers(int numLimit, int numAmount) 
    {

        Random RandomNumber = new Random();

        for (int i = 0; i < numLimit ; i++) //loop to fill up numberHolder array
                                            // with predefined limit of numbers

        {
            numberHolder[i] = i++;
        }

        for (int i = 0; i < numAmount; i++)
        {


            // code to pick unique random numbers no greater than numAmount 
            // and add them to the drawHolder[] array
            drawHolder[i] = RandomNumber.Next(1, numLimit);

        }





        //return the drawHolder array to String
        return null;
    }





}

8条回答
Deceive 欺骗
2楼-- · 2019-01-28 06:42

There are a few options, you could use the Contains method.

numberHolder.Contains(value)

The Any() method.

numberHolder.Any(x=>x == value);
查看更多
戒情不戒烟
3楼-- · 2019-01-28 06:44

In my opinion, you should change your approach.

Instead of thinking "I'll generate random indexes to pick my numbers", where you have to be sure you don't get any duplicates, I would simply shuffle the array and take the X first you need. That way, you don't need to worry about indexes or duplicates.

So your second for loop would be changed to

drawHolder = numberHolder.OrderBy(x => new Guid()).Take(numAmount);

(Please note I've used new Guid() so you can remove your RandomNumber declaration line. As discussed before, a GUID is a unique value and not meant for to be used as a random gen. You could also use x => RandomNumber.Next(), but if you really need a strong and reliable shuffe, read about Fisher-Yates)

You can also replace your numberHolder array with a simple Enumerable.Range

So your whole code would become (And please note I've changed your method name to use C# conventions, method names should be in PascalCase)

public string DrawNumbers(int numLimit, int numAmount) 
{
    drawHolder = Enumerable.Range(0, numLimit).OrderBy(x => new Guid()).Take(numAmount);

    return string.Join(", ", drawHolder);
} 
查看更多
SAY GOODBYE
4楼-- · 2019-01-28 06:47

I would keep it simple:

private Random _rnd = new Random();
public String drawNumbers(int numLimit, int numAmount) 
{
    return String.Join("," ,
        Enumerable
            .Range(1, numLimit)
            .OrderBy(x => _rnd.Next())
            .Take(numAmount));
}

Keep the declaration of the Random instance outside of the method to prevent returning identical sequences if you call the method in quick succession.

查看更多
欢心
5楼-- · 2019-01-28 06:52

Lots of ways to do this. You could sort and then compare if array[i] == array[i+1].

查看更多
Emotional °昔
6楼-- · 2019-01-28 06:56

Sounds like shuffling your array is better than generating random numbers. You could do it like this:

int[] ShuffleArray(int[] array)
{
  Random r = new Random();
  for (int i = array.Length; i > 0; i--)
  {
    int j = r.Next(i);
    int k = array[j];
    array[j] = array[i - 1];
    array[i - 1]  = k;
  }
  return array;
}

Credit goes to @RohitArora.

查看更多
放我归山
7楼-- · 2019-01-28 06:59

It's too late but I use a Method named M_Randomizer created by me.

using System;
class Randomizer
{
    public int[] M_Randomizer(int x)
    {
        bool b = false;
        if (x < -1)
        {
            b = true;
            x = -1 * x;
        }
        if(x == -1)
            x = 0;
        if (x < 2)
            return new int[x];

        int[] site;
        int k = new Random(Guid.NewGuid().GetHashCode()).Next() % 2;
        if (x == 2)
        {
            site = new int[2];
            site[0] = k;
            site[1] = 1 - site[0];
            return site;
        }
        else if (x == 3)
        {
            site = new int[3];
            site[0] = new Random(Guid.NewGuid().GetHashCode()).Next(0, 3);
            site[1] = (site[0] + k + 1) % 3;
            site[2] = 3 - (site[0] + site[1]);
            return site;
        }
        site = new int[x];
        int a = 0, m = 0, n = 0, tmp = 0;
        int[] p = M_Randomizer(3);
        int[] q;

        if (x % 3 == 0)
            q = M_Randomizer(x / 3);
        else
            q = M_Randomizer((x / 3) + 1);
        if (k == 0)
        {
            for (m = 0; m < q.Length; m++)
            {
                for (n = 0; n < p.Length && a < x; n++)
                {
                    tmp = (q[m] * 3) + p[n];
                    if (tmp < x)
                    {
                        site[a] = tmp;
                        a++;
                    }
                }
            }
        }
        else
        {
            while (n < p.Length)
            {
                while (a < x)
                {
                    tmp = (q[m] * 3) + p[n];
                    if (tmp < x)
                    {
                        site[a] = tmp;
                        a++;
                    }
                    m = m + k;
                    if (m >= q.Length)
                        break;
                }
                m = m % q.Length;
                n++;
            }
        }

        a = (new Random(Guid.NewGuid().GetHashCode()).Next() % 2) + 1;
        k = new Random(Guid.NewGuid().GetHashCode()).Next() % 10;
        if (k > 5)
            for (int i = a; i < k; i++)
                while (a < site.Length)
                {
                    if (k % (a + 1) == 0)
                    {
                        tmp = site[a - 1];
                        site[a - 1] = site[a];
                        site[a] = tmp;
                    }
                    a = a + 2;
                }

        k = new Random(Guid.NewGuid().GetHashCode()).Next() % 10;
        if (k > 5)
        {
            n = x / 2;
            k = 0;
            if (x % 2 != 0)
                k = (new Random(Guid.NewGuid().GetHashCode()).Next() % 2);

            p = new int[n + k];
            m = (x - n) - k;
            for (a = 0; m < x; a++, m++)
                p[a] = site[m];

            m = n + k;
            for (a = (x - m) - 1; a >= 0; a--, m++)
                site[m] = site[a];

            for (a = 0; a < p.Length; a++)
                site[a] = p[a];
        }

        int[] site2;
        int[] site3 = new int[x];
        if (b)
            return site;
        else
            site2 = M_Randomizer(-1 * x);

        for (a = 0; a < site.Length; a++)
            site3[site2[a]] = site[a];

        return site3;
    }

    public int[] M_Randomizer(int x, int start)
    {
        int[] dm = M_Randomizer(x);

        for(int a = 0; a < x; a++)
            dm[a] = dm[a] + start;

        return dm;
    }
}
查看更多
登录 后发表回答