【问题标题】:How do I generate a random number in a certain range with Ruby?如何使用 Ruby 生成一定范围内的随机数?
【发布时间】:2011-08-26 01:37:55
【问题描述】:

我正在尝试使用 Ruby 获得 1900 年到 1980 年之间的随机年份。

到目前为止我有:

puts 'the year was: ' +  1900.to_s + rand(1980).to_s

但这只是将 1900 和 0 - 1979 之间的随机数相加,看起来像 19001947。

我认为我遗漏了一些愚蠢的东西,但任何人都可以解释一下吗?

【问题讨论】:

标签: ruby


【解决方案1】:

Ruby 1.9.3

1.9.3p0 :001 > rand(1900..1980)
 => 1946 
1.9.3p0 :002 > rand(1900..1980)
 => 1929 
1.9.3p0 :003 > rand(1900..1980)
 => 1934 

【讨论】:

    【解决方案2】:

    试试看

    (1900 + rand(81)).to_s
    

    路人一目了然

    首先,存在关于字符串连接的问题。问题中的原始代码是将两个字符串(包含数字)连接在一起。示例:

    “1900”+“1920”=“19001920”

    其次,生成的随机数范围存在问题。在这种情况下,由于我们只想要 80 年的范围,我们想要使用 rand(81),而不是 rand(1980)。然后我们把这个结果加到基数上,这将给我们一个介于 1900 和 1980 之间的随机数。

    【讨论】:

    • 这将生成 1900(有时),但永远不会生成 1980。
    • 您误认为这不是字符串连接的问题:1900.to_s 和 rand(80).to_s 都计算为字符串类型的对象,因此“+”操作确实是字符串“+”的过载。这当它更改为 (1900 + rand(80)).to_s, 1900 并且 rand(80) 的结果是数字,然后将结果总和转换为字符串。
    • @Charlie,我认为您错误地阅读了我关于字符串的评论。我的回答是“最初的问题是连接两个字符串”。我相信我们不是同一页。引用我的回答:“首先,存在关于字符串连接的问题。”我的意图是传达这个问题确实有两个问题,第一个是串联问题
    【解决方案3】:
    puts "The year was #{1900 + rand 81}"
    

    【讨论】:

      【解决方案4】:

      是的:你得到了 + 的“字符串连接”重载。试试(1900+rand(80)).to_s

      【讨论】:

        【解决方案5】:

        Ruby 1.8+

        (1900..1980).to_a[rand(80)]
        # or little more Rubyistic
        (1900..1980).to_a.shuffle.first
        

        Ruby 1.9+

        [*1900..1980].sample
        

        【讨论】:

        • 这种方法的缺点是为范围内的每个元素创建了一个中间数组。对于小范围来说,这没什么大不了的。范围很大,比如0..1_000_000_000 可能会很痛苦。
        • @the Tin Man,我认为这是过度设计和过度优化。这是一个特殊的问题,我认为这个问题的解决方案很好:)。它是静态范围(1900..1980),永远不会长成大的东西。我相信,过度工程是水平的。当然,您应该了解您使用的任何方法的所有缺点,但如果它不是目标,则永远不应该使用“最快”的性能。
        • 是的,我更喜欢@Phrogz 解决方案,但就我回答之前明显的直接解决方案而言,我建议这样做只是为了好玩:D
        • @fl00r :因为它效率低下。而不是调用 rand 你正在创建一个可能很大的数组,只是为了调用一个更复杂的随机方法(.sample 确保不返回重复项)。
        • “所有这些副作用对我们的主题来说都不是问题”我不同意。提供包含 OP 现在和将来做出正确决策所需的信息的答案很重要。虽然您的解决方案确实适用于这个特定问题,但 OP 稍后可能会遇到麻烦,因为没有针对该特定用途给出警告。这是要传递的重要信息,并且正在教授如何钓鱼。而且,就过度工程而言,我认为它通过避免潜在的未来问题来进行防御性编程。
        猜你喜欢
        • 2014-01-29
        • 1970-01-01
        • 1970-01-01
        • 2016-05-04
        • 2017-11-06
        • 2010-12-24
        • 2016-02-10
        相关资源
        最近更新 更多