问题
I just wrote the following to utilize the sieve to find the largest prime factor of some natural number greater than 2.
The program builds and runs and works for small test values, but simply crashes for values larger than, say, 1000000.
I wrote this myself--and believe it will probably be extremely inefficient--after finding out what the sieve is about.
Can you please suggest improvements?
Thank you.
//LARGEST PRIME FACTOR w/SIEVE OF ERATHOSTHENES
#include <iostream>
#include <math.h>
using namespace std;
unsigned long long int numberToCheck=0;
void sieve(unsigned long long int checkNumber)
{
checkNumber=numberToCheck;
unsigned long long int root=(int)(sqrt(checkNumber));
unsigned long long int primeFlagger[checkNumber+1];
for(unsigned long long int i=0;i<=checkNumber;i++)
{
primeFlagger[i]=1;
}
primeFlagger[0]=0;
primeFlagger[1]=0;
for(unsigned long long int j=2;j<=checkNumber;j++)
{
if(primeFlagger[j]==1)
{
for(unsigned long long int k=2;(k*j)<=checkNumber;k++)
{
primeFlagger[j*k]=0;
}
}
}
for(unsigned long long int l=checkNumber;l>=0;l--)
{
if(primeFlagger[l]==1)
{
if(checkNumber%l==0)
{
cout<<l<<" is the largest prime factor"<<endl;
break;
}
}
}
}
int main()
{
cout<<"Largest prime factor less then or equal to? "<<endl;
cin>>numberToCheck;
cout<<endl;
cout<<"Retrieving largest prime factor..."<<endl;
sieve(numberToCheck);
return 0;
}
回答1:
Your array unsigned long long int primeFlagger[checkNumber+1];
inside sieve
func is too long. Use array in global scope, outside of any function or dynamic memory allocation.
Also, you dont need unsigned long long
. Its a largest integer data type and you use only one bit of it. Changing type to bool will help you too.
There is other problems:
unsigned long long int root=(int)(sqrt(checkNumber));
- If number is really large,sqrt(checkNumber)
can overflowint
;unsigned long long int primeFlagger[checkNumber+1];
- type ofcheckNumber
is probably larger thanstd::size_t
- the type for array index and larger than largest memory area that can be allocated. You just cant make array size of unsigned long long.checkNumber=numberToCheck;
- You dont need this.numberToCheck
where already passed into function as parametercheckNumber
. Insidesieve
checkNummber will be equal tonumberToCheck
;for(unsigned long long int j=2;j<=checkNumber;j++)
- this loop should ends thenj<=root
. This would be enough to mark all non-primal numbers.
If you really need to work with such large numbers, use segmented sieve.
来源:https://stackoverflow.com/questions/39338281/sieve-of-eratosthenes-prime-factor