如何提高此代码的效率?
假设您必须处理非常大的投入。
#include <iostream>
using namespace std;
int main()
{ //This program finds out the largest prime factor of given input
long int n,big=1;
cin>>n;
for (long int i=2;i<n;i=i+2)
{
if (n%i==0)
big=i;
}
cout<<big;
return 0;
}
答案 0 :(得分:3)
首先,我认为你所拥有的代码无论如何都会给你最大的 prime 因子,它只是给你最大的因素,无论是素数还是复合( 1)
如果你是在最大的素数因子之后(或者如果没有则为零),可以通过重复的整数除法找到它,类似于UNIX factor
程序的许多实现的工作方式,以及以下几行:
def largestPrimeFactor(n):
if n < 2: return 0 # Special case
denom = 2 # Check every denominator
big = 0
while denom * denom <= n: # Beyond sqrt, no factors exist
if n % denom == 0: # Check factor, then divide
big = denom
n = n / denom
else:
denom = denom + 1 # Or advance to next number
if n > big: # What's left may be bigger
big = n
return big
如果您希望甚至更多效率,您可以更改每次循环修改分母的方式。一旦你检查了两个,每个其他素数必须是奇数,这样你就可以避免重新检查偶数,有效地减少了所花费的时间:
def largestPrimeFactor(n):
if n < 2: return 0 # Special case
while n % 2 == 0: n = n / 2 # Check and discard twos
if n == 1: return 2 # Return if it was ALL twos
denom = 3 # Check every denominator
big = 0
while denom * denom <= n: # Beyond sqrt, no factors exist
if n % denom == 0: # Check factor, then divide
big = denom
n = n / denom
else:
denom = denom + 2 # Or advance to next odd number
if n > big: # What's left may be bigger
big = n
return big
还有另一种跳过更多复合材料的方法,它依赖于数学上的事实,除了2
和3
之外,每个其他素数的形式都是6n±1
(2)功能
某些复合材料也有此表单,例如25
和33
,但您可以在此处使用小的低效率。
虽然使用奇数的变化比最初的努力减少了50%,但是这个变为削减了奇数变体的另外33%:
def largestPrimeFactor(n):
if n < 2: return 0 # Special case
while n % 2 == 0: n = n / 2 # Check and discard twos
if n == 1: return 2 # Return if it was ALL twos
while n % 3 == 0: n = n / 3 # Check and discard threes
if n == 1: return 3 # Return if it was ALL threes
denom = 5 # Check every denominator
adder = 2 # Initial value to add
big = 0
while denom * denom <= n: # Beyond sqrt, no factors exist
if n % denom == 0: # Check factor, then divide
big = denom
n = n / denom
else:
denom = denom + adder # Or advance to next denominator,
adder = 6 - adder # alternating +2, +4
if n > big: # What's left may be bigger
big = n
return big
这里的诀窍是从五点开始,交替地在四点加两点:
vv vv (false positives)
5 7 11 13 17 19 23 25 29 31 35 37 41 ...
9 15 21 27 33 39 (6n+3, n>0)
你可以看到它跳过每三个奇数(9, 15, 21, 27, ...
),因为它是三的倍数,这是进一步减少33%的地方。在这种情况下,您还可以看到素数的误报(25
和33
,但会发生更多)。
(1)您的原始标题需要最大的偶数素因子和最有效的查找代码,这将是非常快速的:
if (n % 2 == 0)
cout << 2 << '\n';
else
cout << "None exists\n";
(因为只有一个甚至素数)。但是,我怀疑这是你真正想要的。
(2)将任何非负数除以6。如果余数是0,2或4,则它是偶数,因此非素数(2是这里的特例):
6n + 0 = 2(3n + 0), an even number.
6n + 2 = 2(3n + 1), an even number.
6n + 4 = 2(3n + 2), an even number.
如果余数为3,那么它可以被3整除,因此非素数(3是这里的特例):
6n + 3 = 3(2n + 1), a multiple of three.
只剩下剩余的1和5,这些数字都是6n±1
的形式。因此,处理2
和3
作为特殊情况,从5
开始,然后交替添加2
和4
,您可以保证所有素数(和很少复合材料)将被捕获。