在ruby / rails中生成n个唯一的随机整数

时间:2010-01-04 00:11:07

标签: ruby-on-rails ruby

我试图生成1到最大

之间的n个唯一随机数

我尝试了以下代码但不起作用(返回重复的数字)

r = [ ]
n.times { v = rand(max) while r.include? v ; r << v}

它有什么问题吗?感谢

加入:

最多是数千

n是10

5 个答案:

答案 0 :(得分:8)

不,不,不要随机生成然后检查,生成唯一的数字,然后随机排序

(1..max).sort_by{rand}

或者,在1.9:

(1..max).to_a.shuffle

答案 1 :(得分:3)

我认为你的r.include逻辑是错误的。试试这个:

r = [ ]
while r.length < n 
  v = rand(max)
  r << v unless r.include? v
end

请注意,如果max&lt;这将进入无限循环。 Ñ

答案 2 :(得分:1)

Kernel#rand生成伪随机数。如果安全性成为问题,这应引起关注。

在Rails中使用ActiveSupport::SecureRandom.random_number

此外,Kernel#randActiveSupport::SecureRandom.random_number都可能返回0,您说该值必须介于1和最大之间。

答案 3 :(得分:1)

我建议使用哈希而不是数组,因为比较Array中的数字的复杂性是array.length,而哈希则是1.然后你最终可以将哈希键传输到数组中。

hash = {}   r = [ ]
while hash.length < n
  a = rand(max)
  if !hash_has_key? (a)
     hash(a) = :ok
  end
end

r = hash.keys

如果你测试n = 30000和max = 500000,与使用数组相比,消耗的时间是非常不同的。

答案 4 :(得分:0)

我不确定确切的ruby语法,但作为算法:

list = [1 .. 10000];

nums = [];

while (nums.length < needed) {
    nums.push( list.splice(rand() * list.length) )
}

应该运作得相当好,只要你的范围不是太大而且不需要浪费时间洗牌整个清单