我正在尝试编写一个返回第n个素数的方法。
我已经找到了解决方案,但问题在于我的方法。我创建了一大堆数字似乎处理速度超慢。确切地说(1..104729).to_a
。我选择104729因为最大n
可以是10000而第10000个整数是104729.我正在寻找一种优化方法的方法。
104729值太大了吗?有没有办法写这个,所以我不是在创建一个大型数组?
以下是方法:
def PrimeMover(num)
def is_prime(x)
i = 0
nums = (2..x).to_a
while nums[i] < nums.max
if x % nums[i] != 0
i += 1
else
return false
end
end
return true
end
primes_arr = (3..104729).to_a.select {|y| is_prime(y)}
primes_arr[num]
end
答案 0 :(得分:10)
require "prime"
def find_prime(nth)
Prime.take(nth).last
end
答案 1 :(得分:5)
结合Ruby的内置prime library和lazy enumerator来提升效果:
require 'prime'
(1...100_000).lazy.select(&:prime?).take(100).to_a
或简单地说,正如阿图罗强调的那样:
Prime.take(100)
答案 2 :(得分:1)
你可以使用Ruby的built in #prime?
method,这看起来非常有效。
代码:
require 'prime'
primes_arr = (3..104729).to_a.select &:prime?
在我的机器上运行2-3秒,我觉得有点可以接受。
如果您需要更好的性能,或者您确实需要编写自己的方法,请尝试实施Sieve of Erathostenes。以下是一些Ruby示例:http://rosettacode.org/wiki/Sieve_of_Eratosthenes#Ruby
答案 3 :(得分:1)
这是最佳 is_prime
的试验部门实施,而不依赖于Prime
类:
素数是一个整数,只能被1和它本身整除,1不是素数。因此,我们想知道x
是否分为小于x且大于1的任何内容。因此,我们在2
处开始计数,并以x - 1
结束。
def prime?(x)
return false if x < 2
2.upto(x - 1) do |n|
return false if (x % n).zero?
end
true
end
只要x % n
有余数,我们就可以打破循环并说这个数字不是素数。这样可以避免在整个范围内循环。如果所有可能的数字都用完了,我们就知道数字是素数。
这仍然不是最佳的。为此,您需要sieve或不同的检测算法来进行试验。但这对您的代码来说是一个很大的改进。把第n个给你。