我正在研究一个程序,它从用户获取输入以获得上限,然后使用一种方法来计算从1到N的所有素数。我有一个有效的解决方案,但是我的脑袋一直在告诉我它是可怕的效率低下。
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;
}
虽然上面的代码有效,但似乎进展缓慢
this.limit
高于3500的价值。关于如何提高效率的任何想法,还是我只是偏执狂?帮助赞赏。
您的实现效率非常低,因为它是整数参数大小的二次方。
寻找例如https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes提高复杂性。
我会研究看看是否有一种不同的方法来计算一个数字,你的实现就是在彼此之间嵌套3个循环。 how to factor a number java可能会有所帮助
以下是Eratosthenes筛选的Java实现:
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;
}
我在my blog讨论这个功能。