如何创建一个返回第n个素数的方法?

时间:2014-12-19 10:39:20

标签: ruby primes

我正在尝试编写一个返回第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

4 个答案:

答案 0 :(得分:10)

require "prime"

def find_prime(nth)
  Prime.take(nth).last
end

答案 1 :(得分:5)

结合Ruby的内置prime librarylazy 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个给你。