首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >挑选唯一随机数

挑选唯一随机数
EN

Stack Overflow用户
提问于 2016-01-31 22:41:25
回答 1查看 1.6K关注 0票数 4

我试着用VB.NET随机化一个数字3次。每次我随机选择一个数字,它应该与另外两个数字不同。

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

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

代码语言:javascript
复制
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。

我很感谢你的帮助,谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-31 22:48:22

在所有示例中,RNG是从NET Random类创建的随机数生成器:

代码语言:javascript
复制
Private RNG = New Random()

林克

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

代码语言:javascript
复制
Dim nums = Enumerable.Range(1, 10).
                OrderBy(Function(r) RNG.Next).
                Take(3).
                ToArray()

从1到10之间的所有数字开始,将它们按随机顺序排列,取前3并将它们存储在nums数组中。我使用了多行形式,在.s之后中断来说明这些步骤。

只需根据需要更改范围、大小/计数和Take()元素即可。例如,对于有5个独特数字1-69 (浓缩形式)的彩票:

代码语言:javascript
复制
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()

手册

了解这些事情的逻辑是很好的,所以这是一个手动版本。通过选择和实际检查随机值,这样做是不同的:

代码语言:javascript
复制
' 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个,例如在匹配游戏中,只需将基本的值池加倍,然后将它们按随机顺序排列:

代码语言:javascript
复制
' 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)将根据需要“耗尽”值,而不是指向使用的最后一个时隙(或下一个时隙)的全局索引器:

代码语言:javascript
复制
' 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),因为我们想要它们全部。然后将它们的值存储在堆栈集合中。使用它:

代码语言:javascript
复制
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

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35120454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档