Finding factors of a given integer

76,387

Solution 1

The following code will return a list of all factors of a given number:

public ArrayList<Integer> findFactors(int num) {        
    ArrayList<Integer> factors = new ArrayList<Integer>();

    // Skip two if the number is odd
    int incrementer = num % 2 == 0 ? 1 : 2;

    for (int i = 1; i <= Math.sqrt(num); i += incrementer) {

        // If there is no remainder, then the number is a factor.
        if (num % i == 0) {
            factors.add(i);

            // Skip duplicates
            if (i != num / i) {
                factors.add(num / i);
            }

        }
    }

    // Sort the list of factors
    Collections.sort(factors);

    return factors;
}

This answer improves Sharad Dargan's answer in two ways:

  1. Based on an idea used in this answer, you can speed up the solution by determining the value to increment by, based on whether the number is even or odd.

    Add the following line of code before the for loop:

    int incrementer = num % 2 == 0 ? 1 : 2;
    

    Then change the last part of the loop to:

     i += incrementer
    

    If the number is odd, it then will skip all even numbers, rather than always incrementing by one no matter what.

  2. Sharad stores the upper limit value in a variable and then uses that variable in the for loop:

    int upperlimit = (int)(Math.sqrt(a));
    ...
    for(int i = 1; i <= upperlimit; i+= 1)
    

    Instead, place Math.sqrt(num) directly in the for loop and skip the upper limit variable:

    for (int i = 1; i <= Math.sqrt(num); i += incrementer) {
    

    This will allow you to skip the casting part of the code, creating cleaner code.


Some JUnit test cases you can then use:

@Test
public void test12() {
    FindFactors find = new FindFactors();

    int num = 12;
    List<Integer> factors = Arrays.asList(1, 2, 3, 4, 6, 12);

    assertEquals(factors, find.findFactors(num));
}

@Test
public void test1000000() {
    FindFactors find = new FindFactors();

    int num = 1000000;
    List<Integer> factors = Arrays.asList(1, 2, 4, 5, 8, 10, 16, 20, 25, 32, 40, 50, 64, 80, 100, 125, 160, 200,
            250, 320, 400, 500, 625, 800, 1000, 1250, 1600, 2000, 2500, 3125, 4000, 5000, 6250, 8000, 10000, 12500,
            15625, 20000, 25000, 31250, 40000, 50000, 62500, 100000, 125000, 200000, 250000, 500000, 1000000);

    assertEquals(factors, find.findFactors(num));
}

@Test
public void test1() {
    FindFactors find = new FindFactors();

    int num = 1;
    List<Integer> factors = Arrays.asList(1);

    assertEquals(factors, find.findFactors(num));
}

@Test
public void test0() {
    FindFactors find = new FindFactors();

    int num = 0;
    List<Integer> factors = new ArrayList<Integer>();

    assertEquals(factors, find.findFactors(num));
}

Solution 2

Here is how to get all factors of the given number.

public class Factors {

    public static void main(String[] args){
        int n = 420;

        for(int i=2; i<=n; i++){
            while(n%i==0){
                System.out.println(i + "| " + n);
                System.out.println(" -----");
                n = n/i;
            }
        }
    }
}

Output:

2| 420
 -----
2| 210
 -----
3| 105
 -----
5| 35
 -----
7| 7
 -----

Solution 3

public class Solution {
    public ArrayList<Integer> allFactors(int a) {

        int upperlimit = (int)(Math.sqrt(a));
        ArrayList<Integer> factors = new ArrayList<Integer>();
        for(int i=1;i <= upperlimit; i+= 1){
            if(a%i == 0){
                factors.add(i);
                if(i != a/i){
                    factors.add(a/i);
                }
            }
        }
        Collections.sort(factors);
        return factors;
    }
}

The above solution simply works like calculating prime factors. The difference being for every prime factor we keep calculating the other part of the product i.e the reqd number.

Solution 4

In order to find the factors of a given number, you only need to check upto the square root of the given number.

For example, in order to find the factors of 6, you only need to check till 2.45 (√6). The factors of 6 will be 1 and 2, and their converse numbers, i.e. 3 and 6.

I have made a program that determines the factors of a given number and displays them. Here is the necessary code:

    Scanner input = new Scanner(System.in);

    System.out.print("Enter integer: ");
    long num = input.nextLong();

    for(long i = 1; i <= Math.sqrt(num); i++) {
        if(num % i == 0) {
            System.out.println(i);
            if(i != num/i) {
                System.out.println(num/i);
            }
        }
    }

You just need this program to find the factors of a given number. However, if you want to take it a step further and display the factors arranged in ascending order, then the necessary code is as follows:

    Scanner input = new Scanner(System.in);

    System.out.print("Enter integer: ");
    long num = input.nextLong();

    ArrayList<Long> list1 = new ArrayList<>(), list2 = new ArrayList<>();

    long currentTime = System.currentTimeMillis();

    for(long i = 1; i <= Math.sqrt(num); i++) {
        if(num % i == 0) {
            list1.add(i);
            if(i != num/i) {
                list2.add(num/i);
            }
        }
    }

    int n1 = list1.size() - 1;
    int n2 = list2.size() - 1;

    for(int i = 0; i <= n1; i++) {
        System.out.println(list1.get(i));
    }

    for(int i = n2; i >= 0; i--) {
        System.out.println(list2.get(i));
    }

What this does: This program stores the factors of the number upto the number's square root in one list (list1), and the converse of these numbers in another list (list2). It then prints the elements of both lists (as shown).

Solution 5

There's nothing wrong with your for loop, but a while loop is the wrong thing to be using here. The logic of your for loop is:

  • Set ff to 1.
  • Keep going while ff <= f.
  • After you've done everything in the for loop, add 1 to ff.

This looks like it is exactly as you want.

The while loop isn't right, though. It will continue to do whatever code you write there for as long as ff is a factor of f, so unless you change them in the while code, you'll get an infinite loop. However, changing that to an if statement will give you what you want.

Since you're checking for factors, you don't actually need to check all possibilities up to f - only up to the square root of f. Whenever you find that ff is a factor, output both ff and f/ff as factors, unless f is a sqare number.

Share:
76,387
Wilson
Author by

Wilson

Updated on July 18, 2022

Comments

  • Wilson
    Wilson almost 2 years

    I have something like this down:

    int f = 120;
    for(int ff = 1; ff <= f; ff++){
        while (f % ff != 0){            
    }
    

    Is there anything wrong with my loop to find factors? I'm really confused as to the workings of for and while statements, so chances are they are completely wrong.

    After this, how would I go about assigning variables to said factors?