由於性能是一個問題,我們來比較一下OP的解決方案與@standelaune's和@dimid's。
require 'prime'
require 'fruity'
n = 100_000
m = 20
tst = m.times.map { rand(n) }
#=> [30505, 26103, 53968, 24108, 78302, 99141, 22816, 67504, 10149, 28406,
# 18294, 92203, 73157, 5444, 24928, 65154, 24850, 64219, 68310, 64951]
def op(num) # Alex
divs = []
(1..num).each { |x| if (num % x == 0) then divs << x end }
divs.length
end
def test_op(tst) # Alex
tst.each { |n| op(n) }
end
def pd(num) # divid
num.prime_division.inject(1){ |prod, n| prod *= n[1] + 1 }
end
def test_pd(tst) #divid
tst.each { |n| nfacs_even?(n) }
end
def div(num) # standelaune
oddity = false
(1..num).each{|x| if (num % x == 0) then oddity = !oddity end}
oddity ? "odd" : "even"
end
def test_div(tst) # standelaune
tst.each { |n| div(n) }
end
compare do
_test_op { test_op tst }
_test_div { test_div tst }
_test_pd { test_pd tst }
end
Running each test 16 times. Test will take about 56 seconds.
_test_pd is faster than _test_div by 480x ± 100.0
_test_div is similar to _test_op
我不會感到驚訝的是divid
的方法吸食他人,爲prime_division
用途(實例)的默認主要發電機,Prime::Generator23,也就是說發生器在C語言編寫的,並相對於Prime
子類中的其他發生器而言是快速的。
你基本上計數n次。想想是否有辦法做更少的循環。 – msergeant
我不確定我看到雙循環?我看到1..num是一個將模塊化函數運行到num的循環。但是,這隻讓我從一次循環到數次。 – Alex
如果你正在尋找因素,你只需要計數到n/2。如果你正在尋找素數因子,你只需要計算2的平方根。我建議將n分解爲素因子,並計算這些素因子可以相乘的方法的數量。 –