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洗牌 。