.net – 选择唯一的随机数
我试图在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. 我感谢任何帮助,谢谢. 解决方法
在所有示例中,RNG是从NET Random类创建的随机数生成器:
Private RNG = New Random() LINQ 如果您只需要两个或三个,则可以循环,直到当前选择不在结果集中.但是使用一些扩展方法更简单: 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 由于强力球可以重复第一个数字,因此它来自自己的游泳池.因为我们只想要一个,所以我们不需要一个数组,只需要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 而不是松散的变量,这使用一个列表来保存选择.这样可以轻松查看当前选择是否已被选中.对于不仅仅是几个值,使用HashSet(Of Int32)而不是List来提高性能. 随机对 要创建一个随机的数字组,每个数字包含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() 对于手动方法,您必须检查循环中每个值的计数. ‘用完’精选 另外一个变化是当你需要定期使用一组randoms,但你不知道你需要提前多少.例如BINGO游戏或一副牌的球. 而不是指向最后使用的槽(或下一个使用的槽)的全局索引器,Stack(Of T)(或队列)将根据需要“使用”值: ' 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) 弹出值时,它会自动从集合中删除.如果您使用鞋子的很多值,您将需要检查计数以确保它不是空的.
在绘制3个值后,鞋子仅剩下97个值. 散记 在所有情况下,您的Random生成器应该是您创建一次的表单级对象.永远不要在循环中创建它们,否则你可能会一遍又一遍地获得相同的值. OrderBy(Function(r)RNG.Next)随机化方法通常足以供临时使用,但效率低下.如果您将随机化大型集合和/或经常使用它,您应该考虑使用适当的随机播放,例如the Fisher-Yates shuffle shown here. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |