生成随机,唯一的值C#

时间:2013-01-23 05:54:42

标签: c# .net random unique

我已经搜索了一段时间并且一直在努力寻找这个,我正在尝试生成几个随机的,唯一的数字是C#。我正在使用System.Random,而我正在使用DateTime.Now.Ticks种子:

public Random a = new Random(DateTime.Now.Ticks.GetHashCode());
private void NewNumber()
{
    MyNumber = a.Next(0, 10);
}

我经常打电话给NewNumber(),但问题是我经常会重复数字。有些人建议因为我每次都是随机声明它,它不会产生随机数,所以我把声明放在我的函数之外。除了使用System.Random之外的任何建议或更好的方法?谢谢

17 个答案:

答案 0 :(得分:23)

  

我经常打电话给NewNumber(),但问题是我常常得到   重复的数字。

Random.Next并不保证该号码是唯一的。您的范围也是0到10,您可能会获得重复值。可能是您可以设置int列表并在检查列表中是否包含重复项后在列表中插入随机数。类似的东西:

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);
}

答案 1 :(得分:15)

如果你的范围只有0到9,你可以尝试改组一系列可能的整数。这增加了避免数字生成中任何冲突的好处。

var nums = Enumerable.Range(0, 10).ToArray();
var rnd = new Random();

// Shuffle the array
for (int i = 0;i < nums.Length;++i)
{
    int randomIndex = rnd.Next(nums.Length);
    int temp = nums[randomIndex];
    nums[randomIndex] = nums[i];
    nums[i] = temp;
}

// Now your array is randomized and you can simply print them in order
for (int i = 0;i < nums.Length;++i)
    Console.WriteLine(nums[i]);

答案 2 :(得分:10)

注意,我不建议这样做:)。 这是&#34; oneliner&#34;以及:

//This code generates numbers between 1 - 100 and then takes 10 of them.
var result = Enumerable.Range(1,101).OrderBy(g => Guid.NewGuid()).Take(10).ToArray();

答案 3 :(得分:9)

我发布了一个正确的shuffle算法实现,因为这里发布的另一个不会产生统一的shuffle。

正如另一个答案所述,对于要随机化的少量值,您可以简单地用这些值填充数组,对数组进行混洗,然后使用您想要的许多值。

以下是Fisher-Yates Shuffle(又名Knuth Shuffle)的实现。 (阅读该链接的“实现错误”部分(搜索“始终从每次迭代的整个有效数组索引范围中选择j”),以查看有关此处发布的其他实现的错误的一些讨论。)

using System;
using System.Collections.Generic;

namespace ConsoleApplication2
{
    static class Program
    {
        static void Main(string[] args)
        {
            Shuffler shuffler = new Shuffler();
            List<int> list = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            shuffler.Shuffle(list);

            foreach (int value in list)
            {
                Console.WriteLine(value);
            }
        }
    }

    /// <summary>Used to shuffle collections.</summary>

    public class Shuffler
    {
        /// <summary>Creates the shuffler with a <see cref="MersenneTwister"/> as the random number generator.</summary>

        public Shuffler()
        {
            _rng = new Random();
        }

        /// <summary>Shuffles the specified array.</summary>
        /// <typeparam name="T">The type of the array elements.</typeparam>
        /// <param name="array">The array to shuffle.</param>

        public void Shuffle<T>(IList<T> array)
        {
            for (int n = array.Count; n > 1; )
            {
                int k = _rng.Next(n);
                --n;
                T temp = array[n];
                array[n] = array[k];
                array[k] = temp;
            }
        }

        private System.Random _rng;
    }
}

答案 4 :(得分:1)

根据您的真实情况,您可以执行以下操作:

using System;
using System.Collections.Generic;
using System.Linq;

namespace SO14473321
{
    class Program
    {
        static void Main()
        {
            UniqueRandom u = new UniqueRandom(Enumerable.Range(1,10));
            for (int i = 0; i < 10; i++)
            {
                Console.Write("{0} ",u.Next());
            }
        }
    }

    class UniqueRandom
    {
        private readonly List<int> _currentList;
        private readonly Random _random = new Random();

        public UniqueRandom(IEnumerable<int> seed)
        {
            _currentList = new List<int>(seed);
        }

        public int Next()
        {
            if (_currentList.Count == 0)
            {
                throw new ApplicationException("No more numbers");
            }

            int i = _random.Next(_currentList.Count);
            int result = _currentList[i];
            _currentList.RemoveAt(i);
            return result;
        }
    }
}

答案 5 :(得分:1)

检查这种即用型方法:放入范围&amp;你想要得到的数量。

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 = Random.Range(0, numbersInOrder.Count);
        result[x] = numbersInOrder[randomIndex];
        numbersInOrder.RemoveAt(randomIndex);
    }

    return result;
}

答案 6 :(得分:0)

@Habib's answer相同,但作为功能:

List<int> randomList = new List<int>();
int UniqueRandomInt(int min, int max)
{
    var rand = new Random();
    int myNumber;
    do
    {
       myNumber = rand.Next(min, max);
    } while (randomList.Contains(myNumber));
    return myNumber;
}

如果randomList是类属性,则UniqueRandomInt将在该类的同一实例的上下文中返回唯一整数。如果要使其在全局范围内唯一,则需要将randomList设为静态。

答案 7 :(得分:0)

0到9之间的唯一随机数

      int sum = 0;
        int[] hue = new int[10];
        for (int i = 0; i < 10; i++)
        {

            int m;
            do
            {
                m = rand.Next(0, 10);
            } while (hue.Contains(m) && sum != 45);
            if (!hue.Contains(m))
            {
                hue[i] = m;
                sum = sum + m;
            }

        }

答案 8 :(得分:0)

此控制台应用程序可让您以不同的顺序将字母随机播放五次。

using System;
using System.Linq;

namespace Shuffle
{
    class Program
    {
        static Random rnd = new Random();
        static void Main(string[] args)
        {
            var alphabet = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
            Console.WriteLine("Alphabet : {0}", string.Join(",", alphabet)); 
            for (int i = 0; i < 5; i++)
            {
                var shuffledAlphabet = GetShuffledAlphabet(alphabet);
                Console.WriteLine("SHUFFLE {0}: {1}", i, string.Join(",", shuffledAlphabet));
            }
        }

        static string[] GetShuffledAlphabet(string[] arr)
        {
            int?[] uniqueNumbers = new int?[arr.Length];
            string[] shuffledAlphabet = new string[arr.Length];

            for (int i = 0; i < arr.Length; i++)
            {
                int uniqueNumber = GenerateUniqueNumber(uniqueNumberArrays);
                uniqueNumberArrays[i] = uniqueNumber;
                newArray[i] = arr[uniqueNumber];
            }

            return shuffledAlphabet;
        }

        static int GenerateUniqueNumber(int?[] uniqueNumbers)
        {
            int number = rnd.Next(uniqueNumbers.Length);

            if (!uniqueNumbers.Any(r => r == number))
            {
                return number;
            }

            return GenerateUniqueNumber(uniqueNumbers);
        }
    }
}

答案 9 :(得分:0)

可能有点晚了,但是这里是更合适的代码,例如当您需要使用循环时:

            List<int> genered = new List<int>();

            Random rnd = new Random();

            for(int x = 0; x < files.Length; x++)
            {
                int value = rnd.Next(0, files.Length - 1);
                while (genered.Contains(value))
                {
                    value = rnd.Next(0, files.Length - 1);
                }
                genered.Add(value);

                returnFiles[x] = files[value];
            }

答案 10 :(得分:0)

我注意到,接受的答案一直在将int添加到列表中,并继续使用if (!randomList.Contains(MyNumber))对其进行检查,我认为这种方法的扩展性不佳,尤其是如果您不断要求输入新数字时。

我会相反。

  1. 启动时线性生成列表
  2. 从列表中获取随机索引
  3. 从列表中删除找到的int

这将需要更多的启动时间,但扩展性会好得多。

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;
        }
    }
}

答案 11 :(得分:0)

这是我使用 HashSet 查找N个随机唯一数字的版本。 看起来很简单,因为HashSet只能包含不同的项目。 这很有趣 - 它会比使用List或Shuffler更快吗?

// Note. An `id` property must be defined/accessible in your code.

// Relative path syntax
// NB. `ActivatedRoute` must be injected into the `route` property.
this.router.navigate([{ outlets: { 'section1' : [id, 'edit'] } }, { relativeTo: this.route }]);

// Absolute path syntax
this.router.navigate([{ outlets: { 'section1' : ['dashboard', 'client', id, 'edit'] } }]);

答案 12 :(得分:-1)

嗨,我在这里发布了一个视频,它解释了如何生成唯一的随机数

  public List<int> random_generator(){

  Random random = new Random();

   List<int> random_container = new List<int>;

     do{

       int random_number = random.next(10);

      if(!random_container.contains(random_number){

       random_container.add(random_number)
  }
}
   while(random_container.count!=10);


     return random_container; 
  }

在这里,,,在随机容器中,您将获得10个从0到9(10个数字)的随机数字,这是随机的..谢谢........

答案 13 :(得分:-1)

randomNumber函数返回介于0到100000之间的无整数值

  bool check[] = new bool[100001];
  Random r = new Random();
  public int randomNumber() {
      int num = r.Next(0,100000);
       while(check[num] == true) {
             num = r.Next(0,100000);
     }
    check[num] = true;
   return num;
 }

答案 14 :(得分:-1)

您还可以使用存储每个随机值的dataTable,然后在dataColumn中使用!=值时执行随机方法

答案 15 :(得分:-2)

您可以使用C#的基本随机函数

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

您现在可以在randomno中使用您想要的任何值,但请记住,这将在0100之间生成一个随机数,您可以将其扩展到任何数字。< / p>

答案 16 :(得分:-4)

试试这个:

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

一些探讨:

Guidbase on here:表示全局唯一标识符(GUID)

Guid.newGuid()会生成一个唯一的标识符,例如"936DA01F-9ABD-4d9d-80C7-02AF85C822A8"

并且它在整个宇宙中都是独一无二的base on here

散列码here从我们的唯一标识符

生成唯一的整数

所以Guid.newGuid().GetHashCode()给了我们一个唯一的数字,随机类会产生真正的随机数抛出这个