Efficient program to print all prime factors of a given number

Given a number n, write an efficient function to print all prime factors of n. For example, if the input number is 12, then output should be “2 2 3″. And if the input number is 315, then output should be “3 3 5 7″.

We strongly recommend that you click here and practice it, before moving on to the solution.


Following are the steps to find all prime factors.
1) While n is divisible by 2, print 2 and divide n by 2.
2) After step 1, n must be odd. Now start a loop from i = 3 to square root of n. While i divides n, print i and divide n by i, increment i by 2 and continue.
3) If n is a prime number and is greater than 2, then n will not become 1 by above two steps. So print n if it is greater than 2.

// Program to print all prime factors
# include <stdio.h>
# include <math.h>

// A function to print all prime factors of a given number n
void primeFactors(int n)
{
    // Print the number of 2s that divide n
    while (n%2 == 0)
    {
        printf("%d ", 2);
        n = n/2;
    }

    // n must be odd at this point.  So we can skip one element (Note i = i +2)
    for (int i = 3; i <= sqrt(n); i = i+2)
    {
        // While i divides n, print i and divide n
        while (n%i == 0)
        {
            printf("%d ", i);
            n = n/i;
        }
    }

    // This condition is to handle the case whien n is a prime number
    // greater than 2
    if (n > 2)
        printf ("%d ", n);
}

/* Driver program to test above function */
int main()
{
    int n = 315;
    primeFactors(n);
    return 0;
}

Output:

3 3 5 7

How does this work?
The steps 1 and 2 take care of composite numbers and step 3 takes care of prime numbers. To prove that the complete algorithm works, we need to prove that steps 1 and 2 actually take care of composite numbers. This is clear that step 1 takes care of even numbers. And after step 1, all remaining prime factor must be odd (difference of two prime factors must be at least 2), this explains why i is incremented by 2.
Now the main part is, the loop runs till square root of n not till. To prove that this optimization works, let us consider the following property of composite numbers.
Every composite number has at least one prime factor less than or equal to square root of itself.
This property can be proved using counter statement. Let a and b be two factors of n such that a*b = n. If both are greater than √n, then a.b > √n, * √n, which contradicts the expression “a * b = n”.

In step 2 of the above algorithm, we run a loop and do following in loop
a) Find the least prime factor i (must be less than √n,)
b) Remove all occurrences i from n by repeatedly dividing n by i.
c) Repeat steps a and b for divided n and i = i + 2. The steps a and b are repeated till n becomes either 1 or a prime number.

Thanks to Vishwas Garg for suggesting the above algorithm. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above







Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the link here.

  • Hindhu Jahnavi

    6 is a num it has 2 3 primefactors…3 is prime factor greater than sqaureroot of 6 noo….

  • human

    is n>2 in last step necessary?
    won’t n>1 also work?

  • duskoKoscica

    When it comes to prime numbers it is the problem when you handle the big ones, that way you are in place to check a lot possible ones, there are some algorithms to see if the number is prime. But for this task I would sugest to create some data structure and save primes in it. This way you could use this thing manny times. Now I got idea to even save the …. oK NOW I need to put my thinking hat on.

  • titanium

    What is Time Complexity of above algorithm ?

    • Steven

      Worst Case, I think sqrt(n)*log(n).

    • Steven

      Worst Case, I think sqrt(n)*log(n).

      • titanium

        Can u explain how you got that ?

  • Himanshu chauhan

    Run above algo on # 893025… it will fail….

    • Steven

      It worked for me… 3 3 3 3 3 3 5 5 7 7…

  • Please note that sqrt() function is CPU intensive and since it’s there within the second for loop, it will be invoked for each iteration! This would defeat the very purpose of using the sqrt() function. It would be better to first evaluate the square root just outside the loop, store it inside a variable and then use that variable in the condition of the for loop (space-time trade-off).

    I recently wrote a blog post (http://www.vinaysingh.info/timing-prime-time/) where I did a small benchmark in Java for comparing the prime number generation and got some strange results.

    • Deepak Kumar Sahu

      If “i <= sqrt(n)" is CPU intensive then how about replacing it with "(i^2) <= n"

      • I don’t think that would make a lot of difference because there is no exponentiation operator in C/C++ and the complexity of pow () would O ( log n ).
        As I mentioned using the sqrt () function just before the for statement would solve the problem. Something like:
        limit=(int)sqrt (n);
        for (int i = 3; i <= limit; i = i+2){

        • pravesh

          but the value of n is changed within the loop

          • Right. I missed that. Now, n/2 would probably be better. I would do some benchmarking and then update.

        • Person

          Old, but for ^2 you can just multiply by it self in constant time. =P i*i -> O(1)

  • L

    Wonderful job dude.. seriously cooooolll!!!!!

  • Sackri

    Instead of performing n % 2, and n / 2 in the above function, can’t we simply write n & 1 and n >> 1 ?

    simply,

    while( !(n & 1) ) {
    // print 2;
    n >> 1;
    }

  • susnata

    nice!

  • anonim

    This is fabulous! thank you so much!

  • Rushabh

    200% WORKING solution for above programme for ANY no. :DD

    #include

    void prime(int x);

    int main()

    {

    int number;

    printf(“Enter a no. you want to find prime factors of”);

    scanf(“%d”,&number);

    prime(number);

    printf(“nGOODBYE”);

    return 0;

    }

    void prime(int x)

    {

    int i;

    for(i=2;i<=x;i++)

    {

    if(x!=0)

    {

    if(x%i==0)

    {

    printf("n%dn",i);

    x=x/i;

    prime(x);

    return x;

    }

    }

    }

    }

    • mm

      what does “return x” returns int the final line of function prime?

  • bib

    what is a vishwas garg

    • bol

      chootiya

  • legalroot

    How to get all the factors of a number? with complexity less than n/2
    can we modify above program to get all the factors?

  • vinay singh

    here is the recursion code for this problem…

    #include

    int main()

    {

    int n;

    printf(“enter any no n”);

    scanf(“%d”,&n);

    prime(n);

    return 0;

    }

    int prime(int n)

    {

    int i=5;

    if(n%2==0)

    {

    printf(” 2″);

    return prime(n/2);

    }

    else if(n%3==0)

    {

    printf(” 3″);

    return prime(n/3);

    }

    else if(n>2)

    printf(“%d”,n);

    }

    • Aprajay Gupta

      yaar kuch samajh nahi aaya

  • omnia

    Though am not completely sure but in your third point i.e.

    “If n is a prime number and is greater than 2, then n will not become 1 by above two steps. So print n if it is greater than 2″

    don’t you think that even if (n>1) instead of n>2 it should work in a correct manner???

  • prithvi

    A slight modification to the above code:

     
    #include<iostream>
    #include<cmath>
    using namespace std;
    // function for prime factors
    void primeFactors(int n){
        int primes[25] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
        int i;
        for (i = 0; i <= 24 && primes[i] <= sqrt(n) ; i++)
        {
            if (n%primes[i] == 0)
            {
                cout << primes[i] << " ";
                do
                {
                    n = n/primes[i];
                }while (n%primes[i] == 0);
            }
        }
        //next prime number is 101
        for (i = 101; i  <= sqrt(n) ; i=i+2)
        {
            if (n%i == 0)
            {
                cout << i << " ";
                do
                {
                    n = n/i;
                }while (n%i == 0);
            }
        }
        if (n > 2)
            cout << n;
    }
    // function main
    int main(){
        int n;
        cout << "enter number: ";
        cin >> n;
        primeFactors(n);
    cout << endl;
    return 0;
    }
     
  • magnet

    if you don’t want to print repeating numbers

     
    #include<iostream>
    #include<math.h>
    
    using namespace std;
    void primeFactors(int n)
    {
        int flag=0;
        while(n%2==0)
        {
            if(flag==0)
            cout<<"2";
            flag=1;
            n=n/2;
            }
            int i;
        for(i=3;i<=sqrt(n);i=i+2)
        {   flag=0;
            while(n%i==0)
            {   if(flag==0)
                cout<<i<<" ";
                flag=1;
               n=n/i;
             }
        }
        if(n>2)
        cout<<n;
        
        }
        int main()
        {
            int n;
            cin>>n;
            primeFactors(n);
            system("pause");
            }
    
     
    • prithvi

      Can also use ‘if’ with ‘do…while’

      if (n%i == 0){
      cout << i << " ";
      do{
      n = n/i;
      }while (n%i == 0);
      }

  • srinath

    Dude,your code fails for 14…you cant check only till sqrt(n) because only the smallest prime factor of any number <sqrt(n),not every prime factor of a number<sqrt(n)…

    14=2*7

    sqrt(14)=3.74…

    you will not find 7 for sure…

    /* Paste your code here (You may delete these lines if not writing code) */

    • geekguy

      @srinath:

      You missed the last check.

      let’s say for 14,

      14/2=7. so it will print 2. and n=7 now.

      Now as n is prime so it will not divided further in second loop.

      Now this part,


      if (n > 2)
      printf ("%d ", n);

      will print 7.

      This last loop will print the last Prime number everytime.

      Hope you get my point ! :)

  • Amit Kumar

    When n is a power of 2 , say 1024(2 to the power 10) , then
    the for loop is needlessly executed….
    /* for (int i = 3; i <= sqrt(n); i = i+2) {
    ….
    } */
    To bring optimizations in such cases we should add a statement
    in between the while loop and for loop
    /*if(n==1)
    return;*/
    @admin : Correct me if I am wrong .

    • Amit Kumar

      Now I got it , its not needed . In such a case the conditionin for loop will fail . So such statement is not required . I was wrong .

  • pratheba
     
    /* Paste your code here (You may delete these lines if not writing code) */
    #include <iostream>
    
    bool checkIfNUmberisPrime(int n)
    {
    	int d = (std::pow(double(2),(double(n)))) - 2;
    	int r = (d%n);
    
    	if(r == 0)
    		return true;
    
    	return false;
    }
    
    
    void primeFactor(int n)
    {
    	if(n%2 == 0)
    	{
    		std::cout << "2" << std::endl;
    		n = n/2;
    	}
    
    	int a = std::ceil(sqrt(double(n)));
    	int b2 = a*a - n;
    
    	double bsqrt = sqrt((double)b2);
    	int isqrt = bsqrt;
    	
    	while(bsqrt != isqrt)
    	{
    		a = a+1;
    		b2 = a*a - n;
    		bsqrt = sqrt((double)b2);
    		int isqrt = bsqrt;
    	}
    
    	std::cout << (a - bsqrt) << std::endl;
    
    	if(!(checkIfNUmberisPrime(a+bsqrt)))
    		primeFactor(a+bsqrt);
    	else
    		std::cout << (a + bsqrt) << std::endl;
    
    
    	return;
    }
    
    
    int main()
    {
    	primeFactor(105);
    }