【问题标题】:Why isn't my programming working when I enter the number: 600851475143为什么当我输入数字时我的编程不起作用:600851475143
【发布时间】:2020-01-03 19:32:45
【问题描述】:

我目前正在做来自 Project Euler 的problem 3。这是我需要解决的问题:
数字 600851475143 的最大质因数是多少?
当我输入较小的数字(例如 10,000)时,我的代码按预期编译。但是当我输入问题中的号码时:600851475143,什么也没有发生。
这是我的代码:

    import java.util.ArrayList;
    class problem3{
    public static void main(String args[]){
        ArrayList<Long> rr = findFactors(600851475143L);// rr holds an Array of factors. 
        rr = largestPrime(rr); // rr now holds an Array of factors that are prime.
        int sizeOfrr = rr.size();
        long largestPrimeFactor = rr.get(sizeOfrr-1);// prints the last(largest) prime factor
        System.out.println(largestPrimeFactor);
        /*This loops through all of the prime factors found
        for(int i = 0; i<rr.size(); i++){
            System.out.println(rr.get(i));
        }*/
        System.exit(0);

    }
    // This method returns an array of factors of the Long argument passed into parameter number.
    public static ArrayList<Long> findFactors(Long number){
        ArrayList<Long> factors = new ArrayList<Long>();
        for(Long i= 1L; i<=number; i++){ // Divide number by every single digit upto and including itself
            // Remember, we need to place L or l after an integer to let the compiler know its a long - not an int primitve.
            if(number%i == 0){ // If number modules i is equal to zero, then i is a factor.
                factors.add(i); // Append i to the factors array.
            }
        }
        return factors;
    }
    // Increments the unit divisor, starting at 2L
    /* The goal is to find if primeArray[i] has more than one factor. (Exluding 1 itself)
    The loop begins at 2L. If primeArray[i]%j == 0, counter will increment by one.
    The moment counter hits 2, we know primeArray[i] is not a prime since if it were prime,
    the counter would be set to 1 and only 1 (because counter would only increment when j is
    equal to primeArray[i] or in otherwords, when it is equal to itself. )
    The method below returns an array of all the prime numbers
    */
    public static ArrayList<Long> largestPrime(ArrayList<Long> primeArray){
        int counter =0;
        for(int i = 0; i<primeArray.size(); i++){ // Loops through the prime array
            for(Long j = 2L; j<= primeArray.get(i); j++){
                // (iL)??; jL++) { // 2L/3 for instance
                    if(primeArray.get(i)%j == 0){// Is it a factor?
                        counter++;
                    }
                    if(counter > 1){
                        primeArray.remove(i);
                        counter = 0;
                        break;
                    }
                    if(j == primeArray.get(i)){
                        counter = 0;
                    }
            }
        }
        return primeArray;
    }
}

【问题讨论】:

  • 您可以从这个问题中学到的最重要的事情是如何使用调试器。使用调试器不仅可以帮助发现错误,还可以鼓励您尝试实验,从而帮助您成为专家。
  • 程序可能仍在运行,因为您循环了 600851475143 次。据我所知,欧拉计划问题需要您跳出框框思考,而不是编写直接的程序来蛮力解决问题。

标签: java prime-factoring


【解决方案1】:

什么都没发生

正如 Qbrute 所说,您循环了 600851475143 次。这真的需要很多。

由于您必须找到最大的质因数,因此您不需要找到每个因数,因此您可以跳过每个偶数。
您可以先找到每个主要因素,然后再找到其他几个因素,然后只保留主要因素,只是比较您找到的那些。
此外,第一个循环可以在Math.sqrt(input) 结束。上面的(主要)因素呢?只需输入/因素。
最后,您可以保持数组排序,这样您就可以在第一个之后停止寻找素数。您还应该尽可能使用原语。

这些优化应该足够了。
试试这个:

public static void main(final String[] args) {
    final long n = 600851475143L;
    final long largestPrime = findLargestPrimeFactors(n);
    System.out.println("The largest prime of " + n + " is: " + largestPrime);
}

public static long findLargestPrimeFactors(final long num) {
    final List<Long> factors = new ArrayList<>();

    int index = 0;
    if ((num % 2L) == 0) {
        factors.add(num / 2L);
        factors.add(2L);
        index = 1;
    }

    final long end = Double.valueOf(Math.floor(Math.sqrt(num))).longValue();

    for (long i = 3L; i <= end; i += 2) { // skip every even number
        if ((num % i) == 0) {
            // This way the list is sorted in descending order
            factors.add(index++, (num / i));
            factors.add(index, i);
        }
    }

    final long largestPrime = retainsLargestPrime(factors);

    return largestPrime != 1L ? largestPrime : num; // if largestPrime is 1 it means that num is a prime number
}

private static long retainsLargestPrime(final List<Long> factors) {
    long largestPrime = 1L;

    if ((factors != null) && !factors.isEmpty()) {
        final int size = factors.size();
        for (int i = 0; (i < size) && (largestPrime == 1L); i++) {
            boolean isPrime = true;
            final long l = factors.get(i);
            for (int j = i + 1; (j < size) && isPrime; j++) {
                isPrime = !((l % factors.get(j)) == 0); // stop the inner loop as soon as possible
            }
            if (isPrime) {
                largestPrime = l;
            }
        }
    }
    return largestPrime;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    相关资源
    最近更新 更多