我该如何生成一个介于0
和n
之间的随机数?
我该如何生成一个介于0
和n
之间的随机数?
根据Ruby随机数:
如果您需要一个随机整数来模拟掷骰子,您可以使用:
1 + rand(6)
。掷骰子可以使用2 + rand(6) + rand(6)
模拟。最后,如果您只需要一个随机浮点数,请调用不带参数的
rand
。
正如Marc-André Lafortune在他下面的答案中提到的那样(请给他点赞),Ruby 1.9.2有它自己的Random
类(Marc-André本人帮助调试,因此该功能的目标为1.9.2)。
例如,在这个需要猜测10个数字的游戏中,您可以使用以下方式初始化:
10.times.map{ 20 + Random.rand(11) }
#=> [26, 26, 22, 20, 30, 26, 23, 23, 25, 22]
注意:
通常情况下,使用Random.new.rand(20..30)
(使用Random.new
)不是一个好主意,正如Marc-André Lafortune在他的回答中详细解释的那样。
但是如果你不使用Random.new
,类方法rand
只能接受一个max
值,不能接受Range
。这正如banister在评论中(并且在Random
文档中有所记录)所指出的那样。只有实例方法可以接受Range
,就像“生成具有7位数的随机数”中所示。
这就是为什么Random.new.rand(20..30)
的等效写法是20 + Random.rand(11)
,因为Random.rand(int)
返回“大于等于零且小于参数的随机整数”。20..30
包括30,我需要生成一个在0到11之间、不包括11的随机数。
Random.rand
实际上可以接受一个范围(从1.9.3开始支持)。 - Ajedi32method(:rand)
输出 #<Method: Object(Kernel)#rand>
。所以 rand
是一个 Kernel
方法,可用于每个 Object
。如果你感觉更好,可以调用 self.send(:rand, 0..10)
。 - Eric Duminil虽然你可以使用rand(42-10) + 10
来获取10
和42
之间的随机数(其中10包含在内,而42不包含在内),但自Ruby 1.9.3以来,有一种更好的方法,你可以调用:
rand(10...42) # => 13
通过引用我的backports
gem,可用于所有版本的Ruby。
Ruby 1.9.2还引入了Random
类,因此您可以创建自己的随机数生成器对象,并具有良好的API:
r = Random.new
r.rand(10...42) # => 22
r.bytes(3) # => "rnd"
Random
类本身就是一个随机生成器,因此您可以直接调用:
Random.rand(10...42) # => same as rand(10...42)
关于 Random.new
的注释
在大多数情况下,最简单的方法是使用 rand
或 Random.rand
。每次想要随机数时创建一个新的随机生成器是一个非常糟糕的想法。如果这样做,你将得到初始种子算法的随机属性,与随机生成器本身的属性相比,这些属性是极差的。
如果你使用 Random.new
,因此应该尽可能少地调用它,例如一次性地调用 MyApp::Random = Random.new
,并在其他地方使用它。
以下情况下,Random.new
是有帮助的:
rand
/Random.rand
的顺序Random
对象可以轻松地被序列化)backports
gem 只是一组在 Ruby 1.8.7、1.9.1、1.9.2 中新增但已在 Ruby 中实现的方法集合。我使用 RubySpec 来确保结果与 Ruby 兼容。 - Marc-André LafortuneRandom.new
都是一个可怕的想法。我已经编辑了我的回答。 - Marc-André LafortuneRandom.rand(10..42)
不起作用。Random.rand
类方法不接受一个范围(Ruby 1.9.2p180)。 - horseyguy如果你不仅需要一个数字,而且还需要十六进制或uuid,值得一提的是,在1.9.2+版本中,SecureRandom
模块从ActiveSupport
移植到了Ruby核心中。因此,无需完整的框架:
require 'securerandom'
p SecureRandom.random_number(100) #=> 15
p SecureRandom.random_number(100) #=> 88
p SecureRandom.random_number #=> 0.596506046187744
p SecureRandom.random_number #=> 0.350621695741409
p SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"
SecureRandom.random_number(1000..9999)
。 - JayTarkaSecureRandom.random_number()
不需要范围,因此不行。你可能想要类似 SecureRandom.random_number(10_000)
(表示 0-9999) 或 SecureRandom.random_number(9_000)+1_000
(表示 1000-9999) 这样的东西。 - mwp你可以使用rand
方法生成随机数。传递给rand
方法的参数应该是一个整数
或者一个范围
,并返回在该范围内对应的随机数:
rand(9) # this generates a number between 0 to 8
rand(0 .. 9) # this generates a number between 0 to 9
rand(1 .. 50) # this generates a number between 1 to 50
#rand(m .. n) # m is the start of the number range, n is the end of number range
rand(1..6)
比排名第一的答案中的rand(6)+1
更清晰易懂。 - isomorphismes好的,我明白了。显然有一个内置的(?)函数叫做rand:
rand(n + 1)
这个怎么样?
n = 3
(0..n).to_a.sample
rand
的时间复杂度是O(1)。 - Travis回答该问题最简单的方法:
rand(0..n)
你可以简单地使用random_number
。
如果给出正整数n,则random_number
返回一个整数:0 <= random_number
< n。
像这样使用它:
any_number = SecureRandom.random_number(100)
输出结果将是0到100之间的任意数字。
范围 = 10..50
rand(范围)
或者
范围.to_a.sample
或者
范围.to_a.shuffle(这将打乱整个数组,您可以从这个数组中选择第一个、最后一个或任何一个数字来选择随机数)
range.to_a.sample
是一个糟糕的想法。 - Gregrand(6) #=> gives a random number between 0 and 6 inclusively
rand(1..6) #=> gives a random number between 1 and 6 inclusively
请注意,range选项仅在较新的Ruby版本(我相信是1.9+)中可用。
range
选项仅在 ruby 1.9.3+
版本中可用。至少在我尝试时,在 1.9.2
版本中无法使用。 - Batkins
rand
代码之前使用srand <some_number>
将会给你一个确定性的(即可重复的)伪随机序列,如果你需要的话。https://ruby-doc.org/core-2.5.6/Random.html#method-c-srand - Purplejacket