我试图找到一个大数字的最大素数值,但它需要太长时间。例如,要找到999999999的最大质数,大约需要55秒。我怎样才能改善这个?
require 'prime'
def highestprime num
i = 1
counter = 0
count = -1
factors = []
primes = []
while (i < num/2) #checks for all factors of number
i += 1
if (num%i == 0)
factors.push(i) #adds all factors to the end factors array
end
end
while (counter != factors.length) #goes through whole array
counter += 1
count += 1
if (factors[count].prime?)
primes.push factors[count]
else
next
end
end
puts primes.pop
end
答案 0 :(得分:3)
这是我第一眼看到的:
while (i < num/2)
您只需要转到数字的平方根即可计算出所有因素。伪代码类似于:
factors = []
i = 1
while i * i <= num:
if num % i == 0:
factors.push(i)
factors.push(num/i)
i++
(假设您仍然希望这样做 - 见下文)。
然而,完全没有必要存储所有这些因素,然后寻找最高素数。
由于您按升序查找因子,您也可以按降序同时找到它们,使用&#34;技巧&#34;在上面的第二个factors.push()
调用中 - 如果i
是num
的因子,则num / i
也是如此。
因此,如果素数因子高于平方根,那么你可以使用相同的循环提前退出(因为那些是在降序顺序中找到的,第一个被发现是最高的。)
否则一直走到平方根并获得迄今为止发现的最高值(在这种情况下你需要最后一个,因为你按照升序搜索)。
这个代码就像:
require 'prime'
def highestprime num
i = 1
large = -1
while (i * i <= num)
if (num % i == 0)
if ((num / i).prime?)
return num / i
end
if (i.prime?)
large = i
end
end
i = i + 1
end
return large
end
puts highestprime 999999999
在第二个
下的井中返回结果333667
pax$ time ruby testprog.rb
333667
real 0m0.160s
user 0m0.031s
sys 0m0.124s
这比原来的55秒解决方案快了约350倍,希望能够为您提供足够快的速度: - )
如果您通过以下方式获取流程启动/关闭成本,则甚至更快
require 'benchmark'
Benchmark.bm do |xyzzy|
xyzzy.report {highestprime 999999999}
end
给出:
user system total real
0.000000 0.000000 0.000000 ( 0.000316)
答案 1 :(得分:3)
怎么样:
require 'prime'
999999999.prime_division.last.first #=> 333667
require 'benchmark'
Benchmark.bm do |x|
x.report {999999999.prime_division.last.first}
end
user system total real
0.000000 0.000000 0.000000 ( 0.000088)