不重复的随机数不重复的随机数(Non-repetitive random number)

2019-05-13 12:09发布

从1 - 20生成随机数我需要挑选选择性,它不应该是重复的。

如何做到这一点在C#

注意:我需要遍历像这样

Random rnd = new Random()
rnd.Next(1,20)
for(int i =0; i<=20;i++)
{

}

对于所有的循环数应为1至20

Answer 1:

究竟你“不应该重复”是什么意思? 如果你的意思是你不想得到任何重复,那么你应该基本上都坐号1-20的列表,随机播放它们,然后抓住一个从列表中的头一个时间。 对于一个有效的方式来洗牌的列表,请参阅该堆栈溢出的答案 。

如果你只是意味着你当前的尝试给5,5,5,5,5,5,1,1,1,1,1,1,1,1,2,2,2,2,2等则有机会您正在创建的新实例Random每次挑一些时间:不这样做。 每次创建一个实例时,它会使用当前时间作为“种子”的随机数发生器(除非你指定一个明确)。 这意味着如果你创建快速连续的几个实例,每个将获得相同的种子,因此给予相同的数字序列。

相反,使用的单个实例Random和重复使用。 (请注意,这不是线程安全的,虽然,这是一种痛苦。)例如:

private static readonly Random Rng = new Random();

public int NextNumber()
{
    return Rng.Next(20) + 1;
}

这不会是线程安全的,但我们知道这是一个问题。 另一种方法是,有时到通过Random进入方法中(通常是更复杂的,当然):

public int NextNumber(Random rng)
{
    return rng.Next(20) + 1;
}

然后调用者可以适当地重用实例。

如果你想生成随机数的线程安全的方式,你可能想看看我StaticRandom类MiscUtil 。

(请注意,使用rng.Next(1, 21)也将很好地工作-我碰巧喜欢上面,因为我认为它减少约包容/独家边界的猜测版本,但它是个人喜好的问题。)



Answer 2:

此方法将产生所有的数字,并没有数字将重复:

/// <summary>
/// Returns all numbers, between min and max inclusive, once in a random sequence.
/// </summary>
IEnumerable<int> UniqueRandom(int minInclusive, int maxInclusive)
{
    List<int> candidates = new List<int>();
    for (int i = minInclusive; i <= maxInclusive; i++)
    {
        candidates.Add(i);
    }
    Random rnd = new Random();
    while (candidates.Count > 0)
    {
        int index = rnd.Next(candidates.Count);
        yield return candidates[index];
        candidates.RemoveAt(index);
    }
}

您可以使用它像这样:

Console.WriteLine("All numbers between 0 and 20 in random order:");
foreach (int i in UniqueRandom(0, 20)) {
    Console.WriteLine(i);
}


Answer 3:

IEumerable的实现,基于Hallgrim的答案:

public class UniqueRandoms : IEnumerable<int>
{
    Random _rand = new Random();
    List<int> _candidates;

    public UniqueRandoms(int maxInclusive)
        : this(1, maxInclusive)
    { }

    public UniqueRandoms(int minInclusive, int maxInclusive)
    {
        _candidates = 
            Enumerable.Range(minInclusive, maxInclusive - minInclusive + 1).ToList();
    }

    public IEnumerator<int> GetEnumerator()
    {
        while (_candidates.Count > 0)
        {
            int index = _rand.Next(_candidates.Count);
            yield return _candidates[index];
            _candidates.RemoveAt(index);
        }
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}


Answer 4:

我做了一个这样一段时间回来。 我不知道如何比较远表现为效率,随机性等其他方法,但它似乎工作:

List<int> integers = new List<int>() { 1, 2, 3, 4, 5, 6,7, 8, 9, 10, 11, 12 };

Random rnd = new Random();

var ints = from i in integers
           orderby rnd.Next(integers.Count)
           select i;


Answer 5:

从MSDN

“提高随机性的一种方法是使种子值随时间变化的。”

另一个事实

你应该“建立一个随机随着时间的推移产生许多随机数。” 这将提高随机生成



Answer 6:

class Program
{
    static void Main(string[] args)
    {        
        List<int> list = new List<int>();
        int val;
        Random r;
        int IntialCount = 1;
        int count = 7 ;
        int maxRandomValue = 8;

        while (IntialCount <= count)
        {
            r = new Random();
            val = r.Next(maxRandomValue);
            if (!list.Contains(val))
            {
                list.Add(val);
                IntialCount++;
            }

        } 
    }
}


Answer 7:

下面的方法是很好的方式,我用在这里是字符串,你可以改变任何你想要...名单的类型,试试吧:

            List<string> NamesList = new List<string>() { "Name1", "Name2", "Name3", "Name4", "Name5" };
            Random rnd = new Random();
            //Now to get random of the above "Without Repeating.."
            for (int i = 0; i <= NamesList.Count - 1; i++)
            {
                int TheSelectedRand = rnd.Next(NamesList.Count);
                string MyRandNumber = NamesList[TheSelectedRand];

                //Print or use your item here

                NamesList.Remove(NamesList[TheSelectedRand]);
            }


Answer 8:

吹塑代码生成0 65之间唯一的随机数 - 92和在阵列中返回唯一的随机数。

public static int[] RandomNumbers_Supplier()
        {
            Random R = new Random();
            int[] RandomNumbers = new int[65];
            int k = 0, Temp;
            bool IsRepetitive = false;
            while (k < 65)
            {
                Temp = R.Next(0, 92);
                for (int i = 0; i < 65; i++)
                {
                    IsRepetitive = false;
                    if (RandomNumbers[i] == Temp)
                    {
                        IsRepetitive = true;
                        break;
                    }                    
                }
                if (!IsRepetitive)
                {
                    RandomNumbers[k] = Temp;
                    k++;
                }
            }
            return(RandomNumbers)
        }


Answer 9:

static void Main(string[] args)
{
    //Randomize 15 numbers out of 25 - from 1 to 25 - in ascending order
    var randomNumbers = new List<int>();
    var randomGenerator = new Random();
    int initialCount = 1;

    for (int i = 1; i <= 15; i++)
    {
        while (initialCount <= 15)
        {
            int num = randomGenerator.Next(1, 26);
            if (!randomNumbers.Contains(num))
            {
                randomNumbers.Add(num);
                initialCount++;
            }
        }
    }
    randomNumbers.Sort();
    randomNumbers.ForEach(x => Console.WriteLine(x));
}


文章来源: Non-repetitive random number
标签: c# random