简体   繁体   中英

I'm trying to find prime factors of any number through my code. But for large numbers, my code is not terminating. Why?

I'm trying to find the prime factors of any given number through this code. This code is working perfectly for small numbers but for larger numbers(like 12345678), the program is not terminating. What's wrong??


using namespace std;
bool isPrime(int i)
{

    for(int k=2;k<i;k++)
    {
        if(i%k==0)
        {
            return false;
        }
    }
    if(i==1)
    {
        return false;
    }
    return true;
}
int main()
{
    int n;
    cout<<"Enter number"<<endl;
    cin>>n;
    for(int i=2;i<n;i++)
    {
        if(isPrime(i))
        {
            int x=n;
           while(n%i==0)
            {
                cout<<i<<endl;
                n=n/i;
            }
            n=x;
        }

    }
    if(isPrime(n))
    {
        cout<<n<<endl;
        cout<<1<<endl;
    }
    return 0;
}

You have a pretty good prime factoring algorithm here, except that you have overthought a few bits. The check if i is prime is only needed because you keep restoring n after you divide out the prime factors you find.

Remember that if you take your N and then divide all of the 2 factors out, then no even number is going to be a divisor of the remainder. In the same fashion, if you divide out the 3 factors, then no number divisible by 3 is going to be a divisor of the remainder.

Or in other words: If you count up from 2 and divide out all the divisors, then every divisor you find (in the remainder of N) must be a prime - because in order for a non-prime to be a divisor, that numbers prime factors must also be divisors, but all smaller primes have already been divided out.

Using that logic, I have cut a few superfluous parts of your algorithm out:

void printPrimes(int n)
{
    for (int i = 2;i < n;i++)
    {
        //if (isPrime(i))
        //{
            //int x = n;
            while (n % i == 0)
            {
                cout << i << endl;
                n = n / i;
            }
            //n = x;
        //}

    }
    //if (isPrime(n))
    //{
        cout << n << endl;
    //}
}

If we clean that a bit, and change the outer loop condition a bit (so that the largest prime won't have to be printed after the loop), we end up with this:

void printPrimes(uint64_t n)
{
    for (int i = 2;n > 1;i++)
    {
        while (n % i == 0)
        {
            cout << i << endl;
            n = n / i;
        }
    }
}

Edit: My point here was to point out that OP already got a pretty close to a good algorithm on his own (and for the size of number he posted this works really well), but as pointed out in comments it can still be done better. For example like this:

void printPrimes(uint64_t n)
{
    while (n % 2 == 0)
    {
        std::cout << 2 << '\n';
        n = n / 2;
    }

    for (uint64_t i = 3;i * i <= n;i += 2)
    {
        while (n % i == 0)
        {
            std::cout << i << '\n';
            n = n / i;
        }
    }

    if (n > 1)
        std::cout << n << '\n';
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM