Generating random, unique values C#

前端 未结 17 1152
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-22 14:26

I\'ve searched for a while and been struggling to find this, I\'m trying to generate several random, unique numbers is C#. I\'m using System.Random, and I\'m us

相关标签:
17条回答
  • 2020-11-22 14:51

    I'm calling NewNumber() regularly, but the problem is I often get repeated numbers.

    Random.Next doesn't guarantee the number to be unique. Also your range is from 0 to 10 and chances are you will get duplicate values. May be you can setup a list of int and insert random numbers in the list after checking if it doesn't contain the duplicate. Something like:

    public Random a = new Random(); // replace from new Random(DateTime.Now.Ticks.GetHashCode());
                                    // Since similar code is done in default constructor internally
    public List<int> randomList = new List<int>();
    int MyNumber = 0;
    private void NewNumber()
    {
        MyNumber = a.Next(0, 10);
        if (!randomList.Contains(MyNumber))
            randomList.Add(MyNumber);
    }
    
    0 讨论(0)
  • 2020-11-22 14:51

    You could also use a dataTable storing each random value, then simply perform the random method while != values in the dataColumn

    0 讨论(0)
  • 2020-11-22 14:52

    You can use basic Random Functions of C#

    Random ran = new Random();
    int randomno = ran.Next(0,100);
    

    you can now use the value in the randomno in anything you want but keep in mind that this will generate a random number between 0 and 100 Only and you can extend that to any figure.

    0 讨论(0)
  • 2020-11-22 14:53

    I noted that the accepted answer keeps adding int to the list and keeps checking them with if (!randomList.Contains(MyNumber)) and I think this doesn't scale well, especially if you keep asking for new numbers.

    I would do the opposite.

    1. Generate the list at startup, linearly
    2. Get a random index from the list
    3. Remove the found int from the list

    This would require a slightly bit more time at startup, but will scale much much better.

    public class RandomIntGenerator
    {
        public Random a = new Random();
        private List<int> _validNumbers;
    
        private RandomIntGenerator(int desiredAmount, int start = 0)
        {
            _validNumbers = new List<int>();
            for (int i = 0; i < desiredAmount; i++)
                _validNumbers.Add(i + start);
        }
    
        private int GetRandomInt()
        {
            if (_validNumbers.Count == 0)
            {
                //you could throw an exception here
                return -1;
            }
            else
            {
                var nextIndex = a.Next(0, _validNumbers.Count - 1);
                var number    = _validNumbers[nextIndex];
                _validNumbers.RemoveAt(nextIndex);
                return number;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 14:53

    Try this:

    private void NewNumber()
      {
         Random a = new Random(Guid.newGuid().GetHashCode());
         MyNumber = a.Next(0, 10);
      }
    

    Some Explnations:

    Guid : base on here : Represents a globally unique identifier (GUID)

    Guid.newGuid() produces a unique identifier like "936DA01F-9ABD-4d9d-80C7-02AF85C822A8"

    and it will be unique in all over the universe base on here

    Hash code here produce a unique integer from our unique identifier

    so Guid.newGuid().GetHashCode() gives us a unique number and the random class will produce real random numbers throw this

    Sample: https://rextester.com/ODOXS63244

    generated ten random numbers with this approach with result of:

    -1541116401
    7
    -1936409663
    3
    -804754459
    8
    1403945863
    3
    1287118327
    1
    2112146189
    1
    1461188435
    9
    -752742620
    4
    -175247185
    4
    1666734552
    7
    

    we got two 1s next to each other, but the hash codes do not same.

    0 讨论(0)
  • 2020-11-22 14:55

    This is a unity only answer:

    Check this ready-to-use method: Give in a range & count of number you want to get.

    public static int[] getUniqueRandomArray(int min, int max, int count) {
        int[] result = new int[count];
        List<int> numbersInOrder = new List<int>();
        for (var x = min; x < max; x++) {
            numbersInOrder.Add(x);
        }
        for (var x = 0; x < count; x++) {
            var randomIndex = UnityEngine.Random.Range(0, numbersInOrder.Count);
            result[x] = numbersInOrder[randomIndex];
            numbersInOrder.RemoveAt(randomIndex);
        }
    
        return result;
    }
    
    0 讨论(0)
提交回复
热议问题