程序需要永远运行

时间:2013-09-05 10:21:21

标签: java

public class Problem_3 {
    public static void main(String... args) {
        long limit = 600851475143L;
        long largestPrimeFactor = 0;

        for (long number = 2; number < limit; number++) {
            if (isPrime(number)) {
                if ((limit % number == 0)){
                    largestPrimeFactor = number; 
                }
            }
        }       
        System.out.println(largestPrimeFactor);
    }

    public static boolean isPrime(long number) {
        for (int i = 2; i < number; i++) {
            if (number % i == 0) {
                return false; 
            }
        }
        return true; 
    }
}

我确定,上面的程序不是无限循环。我使用limit = 13195;进行了测试,得到了期望的结果29

我不明白为什么我的CPU会永远运行它。

EDIT: 它是我的ProjectEuler.net问题编号3的代码。

6 个答案:

答案 0 :(得分:8)

您的算法的时间复杂度为O(n ^ 2),因此对于较大的限制值,它不是非常有效。

所以它很慢,因为你使用的算法很差。

答案 1 :(得分:5)

代码的时间复杂度为O(N ^ 2)。所以它对于大数字来说不是一个好的算法。可能的建议如下 -

您对最大的素数因素感兴趣,那么为什么不从最大值开始呢?

    for (long number = limit-1; number > 1; number--) {
        if (isPrime(number)) {
            if ((limit % number == 0)){
                largestPrimeFactor = number;
                 break; 
            }
        }
    }  

虽然时间复杂度保持不变,但这肯定会比现有算法缩短你的时间。

但是,究竟什么是时间复杂性???你怎么计算它.. ??什么是O(N ^ 2)?请解释

 for (long number = 2; number < limit; number++)

以上是您的第一个for循环,您将拥有n iterations。在此内容中,您调用了isPrime()函数,该函数再次在for (int i = 2; i < number; i++)中有{for循环n iterations。所以基本上你有两个for循环,一个在另一个里面,这使你的时间复杂度n * n = n ^ 2

答案 2 :(得分:2)

这就是原因。

long limit = 600851475143L;

和O(n ^ 2)算法,n是这个长数600851475143L

答案 3 :(得分:2)

你将每个no传递给isPrime(长号)方法&amp;你再次使用for循环“for(int i = 2; i&lt; number; i ++){”每次运行另一个(数字-1)。表示您运行的是600851475141 * 600851475141次。

你可以知道需要花多少时间...........可能你需要一个超级补偿......

快乐编码

答案 4 :(得分:1)

正如所有人所说,你的代码不是非常节省时间,但是看看代码,我猜你正在努力找到最大的主要因素,你可以实际尝试Sieve of Eratosthenes生成所有素数然后找到从后面因素。

import java.util.LinkedList;

 class Sieve{



       public static LinkedList<Long> sieve(long n){
               if(n < 2) return new LinkedList<Long>();
               LinkedList<Long> primes = new LinkedList<Long>();
               LinkedList<Long> nums = new LinkedList<Long>();

               for(long i = 2;i <= n;i++){ //unoptimized
                       nums.add(i);
               }

               while(nums.size() > 0){
                       long nextPrime = nums.remove();
                       for(long i = nextPrime * nextPrime;i <= n;i += nextPrime){
                               nums.removeFirstOccurrence(i);
                       }
                       primes.add(nextPrime);
               }
               return primes;
       }
}

上面的代码返回 素数链接列表 从最后开始使用此开头并获得最大因素。

注意:在运行输入 600851475143L

之前,增加 jvm的堆大小

答案 5 :(得分:1)

由于你的循环嵌套(一个循环限制在主循环中,另一个循环在该循环中调用,在isPrime中),算法的时间复杂度为O(n ^ 2)。

这是表示算法为不同大小的输入解决不同问题需要多长时间的标准方法。

在你的情况下,大小是限制(600851475143L)所以要解决问题,这将需要“订单600851475143 ^ 2”,相比之下,“10 ^ 2(即100)”,如果你有限制为10(例如)

因此,如果限制为10的版本需要100毫秒(10平方),那么您的600851475143版本将需要361022495181519000000000毫秒(即600851475143L平方,如果我在那里有一些零错误,则道歉)

时间复杂度的其他例子是O(1)或恒定时间,其中算法在不考虑大小或O(n)或线性时间的情况下花费相同的时间,其中所花费的时间与大小