我试着用VB.NET随机化一个数字3次。每次我随机选择一个数字,它应该与另外两个数字不同。
例如,我有3个整数。Int1,Int2和Int3。我会在1-10之间随机化Int1,然后在1-10之间随机化Int2,但是这个值不应该等于在Int1中随机化的值,对于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。
我很感谢你的帮助,谢谢。
发布于 2016-01-31 22:48:22
在所有示例中,RNG是从NET Random类创建的随机数生成器:
Private RNG = New Random()林克
如果您只需要两个或三个,您可以循环,直到当前的选择不在结果集中。但是使用一些扩展方法就更简单了:
Dim nums = Enumerable.Range(1, 10).
OrderBy(Function(r) RNG.Next).
Take(3).
ToArray()从1到10之间的所有数字开始,将它们按随机顺序排列,取前3并将它们存储在nums数组中。我使用了多行形式,在.s之后中断来说明这些步骤。
只需根据需要更改范围、大小/计数和Take()元素即可。例如,对于有5个独特数字1-69 (浓缩形式)的彩票:
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因为Powerball可以是第一个数字的重复,所以它来自自己的池。因为我们只需要一个数组,所以我们不需要数组,只需要一个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而不是松散的vars,这使用一个列表来保存选择。这使得查看当前的选择是否已经被选中变得非常容易。对于不只是几个值的情况,使用HashSet(Of Int32)而不是列表来提高性能。
随机对
要创建一个随机的数字集,每组2个,例如在匹配游戏中,只需将基本的值池加倍,然后将它们按随机顺序排列:
' 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()对于手动方法,您必须检查循环中每个值的计数。
“用上”
另一种变化是,当你需要定期使用一堆随机画时,你不知道预先需要多少。例如,一个宾果游戏或一副牌的球。
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生成器都应该是一个表单级别的对象,您可以一次性创建。永远不要在循环中创建它们,否则您可能会得到一个又一个相同的值。
随机化的OrderBy(Function(r) RNG.Next)方法通常适合于随意使用,但效率很低。如果您要随机处理大集合和/或频繁使用它,您应该考虑使用适当的洗牌,如the Fisher-Yates shuffle shown here。
https://stackoverflow.com/questions/35120454
复制相似问题