-1

I am working on a program that takes input from the user to get an upper limit and then uses a method to calculate all of the prime numbers from 1 to N. I have a working solution, but my head keeps bugging me that it is horribly inefficient.

 public ArrayList<Integer> primeNumbers()
{
    long startTime = System.nanoTime();
    ArrayList<Integer> prime = new ArrayList<Integer>();
    ArrayList<Integer> factorList;
    for (int i = 2; i <= this.limit; i+=1)
    {
        factorList = factors(i);
        if (factorList.size() == 2 && factorList.contains(1) && factorList.contains(i))
        {
            prime.add(i);
        }
    }
    long endTime = System.nanoTime();
    long totalTime = endTime - startTime;
    System.out.println("The total time was: " + totalTime);
    return prime;

}

public ArrayList<Integer> factors(int i)
{
    ArrayList<Integer> factor = new ArrayList<Integer>();

    for (int a = 1; a <= i; a+=1)
    {
        for (int b = 1; b<=i; b+=1)
        {
            if (a*b == i)
            {
                if (factor.contains(a) == false)
                     factor.add(a);
                if (factor.contains(b) == false)
                     factor.add(b);
            }
        }
    }
    return factor;
}

Although the code above works, it seems to go very slowly for

this.limit

values above 3500. Any ideas on how I could improve the efficiency, or am I just being paranoid? Help appreciated.

jaguar
  • 152
  • 10
  • 6
    Possible duplicate of [Program to find all primes in a very large given range of integers](https://stackoverflow.com/questions/10703699/program-to-find-all-primes-in-a-very-large-given-range-of-integers) – takendarkk Mar 02 '18 at 19:03
  • You don't need to find all of the factors. You only need to loop thru 1 - (n/2) and check modulus. If n modulus loopCounter == 0 then return false – bcr666 Mar 02 '18 at 19:06
  • [** O Gℎ, !**](https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth). that's how you know whether it is horribly inefficient (~n^2 and above), or just inefficient (~n^1.5). Tolerable sieves run at about ~n^1.2, good at ~n^1.1 and below. – Will Ness Mar 03 '18 at 17:15

3 Answers3

0

Your implementation has a very poor efficiency, since it's quadratic over the size of the integer parameter.

Look for e.g. https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes to improve complexity.

0

i would look into seeing if there is a different way to factor a number, with your implementation you are nesting 3 for loops inside each other. how to factor a number java may help

Zach Metcalf
  • 21
  • 1
  • 4
0

Here is an implementation in Java of the Sieve of Eratosthenes:

public static LinkedList sieve(int n)
{
    BitSet b = new BitSet(n);
    LinkedList ps = new LinkedList();

    b.set(0,n);

    for (int p=2; p<n; p++)
    {
        if (b.get(p))
        {
            ps.add(p);
            for (int i=p+p; i<n; i+=p)
            {
                b.clear(i);
            }
        }
    }

    return ps;
}

I discuss this function at my blog.

user448810
  • 17,381
  • 4
  • 34
  • 59