select唯一的随机数字

我试图在VB.NET中随机化一个数字3次。 每次我随机化一个数字,它应该与其他两个数字不同。

例如,我有3个整数。 Int1,Int2和Int3。 我会在1-10之间随机化Int1,然后我会在1-10之间随机化Int2,但是这个值不应该等于Int1中随机化的值I,Int3也是一样,它不应该等于Int1和Int2。

我已经想出了如何随机化一个数字,这是我正在使用的代码:

Dim RndNumber As Random Dim num,num2 As Integer RndNumber = New Random num = RndNumber.Next(1, 11) num2 = RndNumber.Next(1, 11) 

现在我被困在如何让num2随机1-10之间的数字不等于num。

我感谢任何帮助,谢谢。

在所有例子中, RNG是一个随机数发生器,它是由NET Random类创build的:

 Private RNG = New Random() 

LINQ

如果你只需要两三个,你可以循环,直到当前select不在结果集中。 但是使用一些扩展方法更简单:

 Dim nums = Enumerable.Range(1, 10). OrderBy(Function(r) RNG.Next). Take(3). ToArray() 

这从1到10之间的所有数字开始,将它们按随机顺序排列,将前3个数字存储在nums数组中。 我用了多行的forms,打破了. 以说明步骤。

只需要根据需要更改范围,大小/数量和Take()元素。 例如,像一个彩票有五个独特的数字1-69(浓缩forms):

 Dim winners = Enumerable.Range(1, 69).OrderBy(Function(r) RNG.Next()).Take(5).ToArray() Dim powerball = Enumerable.Range(1, 26).OrderBy(Function(r) RNG.Next()).Take(1).First 

由于powershell球可以重复第一个数字,它来自自己的游泳池。 由于我们只需要一个,我们不需要一个数组,只需要First()

手册

知道这些事情的逻辑是很好的,所以这里显示一个手册版本。 这是不同的,通过挑选和实际检查随机值:

 ' picked value storage Dim picks As New List(Of Int32) Dim pick As Int32 ' current candidate Do pick = RNG.Next(1, 11) If picks.Contains(pick) = False Then picks.Add(pick) End If Loop Until picks.Count = 3 

而不是松散的variables,这使用一个列表来举行选秀。 这可以很容易地看到当前select是否已被选中。 对于不止一个值,使用HashSet(Of Int32)而不是List来获得性能。

随机对

要创build一个随机的数字集合 ,每个数字有两个,比如一个匹配的游戏,只需将基础数值池加倍,然后按随机顺序放入:

 ' create pool of 2 values each for 1-13 Dim nums = Enumerable.Range(1, 13).ToArray() ' concat the set to make 2 of each value, randomize Dim pool = nums.Concat(nums).OrderBy(Function(r) RNG.Next).ToArray() 

对于手动方法,您将不得不检查循环中每个值的计数。

“用尽”精选

还有一个变化就是当你需要一个定期使用的随机池,但是你不知道你需要多less。 例如,一个BINGO游戏或一副牌的球。

而不是全局索引器指向最后使用的槽(或下一个使用的槽), Stack(Of T) (或Queue )会根据需要“耗尽”值:

 ' create, randomize pool of 100 ints Dim nums = Enumerable.Range(1, 100).OrderBy(Function(r) RNG.Next).ToArray ' use array to create Stack<T> Dim shoe As New Stack(Of Int32)(nums) ' same as: Dim shoe = New Stack(Of Int32)(Enumerable.Range(1, 100). OrderBy(Function(r) RNG.Next).ToArray()) 

这与100个整数开始基本相同,随机化并存储在一个数组中,但没有Take(n)因为我们需要它们全部。 然后它们的值被存储在一个堆栈集合中。 使用它:

 Console.WriteLine(shoe.Count) For n As Int32 = 1 To 3 Console.WriteLine("Picked #{0}", shoe.Pop) Next Console.WriteLine(shoe.Count) 

当你Pop一个值时,它会自动从集合中删除。 如果你使用了很多鞋子的价值,你会想检查计数,以确保它不是空的。

100
摘了#12
摘#69
摘了#53
97

绘制3个值后,鞋子只剩下97个值。

散记

在所有情况下,你的Random生成器应该是你创build一次的表单级对象。 千万不要在循环中创build它们,否则您可能会得到相同的值。

随机化的OrderBy(Function(r) RNG.Next)方法对于临时使用来说通常是足够好的,但效率不高。 如果你将随机大集合和/或经常使用它,你应该考虑使用一个适当的洗牌,如这里显示的Fisher-Yates洗牌 。