生成随机,唯一的值C#

Chr*_*eut 28 .net c# 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);
}
Run Code Online (Sandbox Code Playgroud)

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

Hab*_*bib 22

我经常给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);
}
Run Code Online (Sandbox Code Playgroud)

  • +1.对于任何超过10个列表的内容都是糟糕的选择,HashSet会更好.并且没有必要以这种方式初始化随机 - 无论如何,在默认构造函数中完成类似的代码...... (2认同)
  • 算法复杂度很差。这不应该作为答案。 (2认同)
  • 真的吗?这是一个非常糟糕的算法。不要使用它! (2认同)

its*_*e86 16

如果范围仅为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]);
Run Code Online (Sandbox Code Playgroud)

  • @ thepirat000唯一真正的原因是速度.对于10个元素,它显然没有区别,但它适用于大型集合.OrderBy()可能是O(N log N)算法,其中shuffle是O(N). (2认同)

JOS*_*Ftw 11

注意,我不推荐这个:). 这里也是一个"oneliner":

//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();
Run Code Online (Sandbox Code Playgroud)


Mat*_*son 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;
    }
}
Run Code Online (Sandbox Code Playgroud)