【问题标题】:Project Euler #3 in Java; program not outputting resultJava中的Euler项目#3;程序不输出结果
【发布时间】:2020-03-27 15:46:30
【问题描述】:

我正在尝试解决 Project Euler 中的问题 3:

13195 的质因数是 5、7、13 和 29。

600851475143 的最大质因数是多少?

这是我的代码:

import java.util.ArrayList;

public class Test {
    public static void main(String[] args){
        long max = 600851475143L;
        ArrayList<Long> primes = new ArrayList<>();
        primes.add((long) 2);
        boolean prime = true;
        for (long i = 3; i <= max; i += 2){
            for (long j = 3; j < Math.sqrt(i); j++){
                if (i % j == 0){
                    prime = false;
                    break;
                }
            }
            if (prime) primes.add(i);
            else prime = true;
        }
        for (int i = primes.size() - 1; i >= 0; i--){
            if (max % primes.get(i) == 0){
                System.out.println(primes.get(i));
                return;
            }
        }
    }
}

代码没有输出任何东西,它只是给了我一个空白屏幕。请不要为我解决问题,请告诉我是什么错误导致它无法输出任何内容。

【问题讨论】:

  • 程序是否停止运行?如果没有,那可能意味着生成素数的程序部分花费了太长时间。
  • @Nosrep 事实上,它永远不会停止。我没注意到。

标签: java primes


【解决方案1】:

当你没有计算所有素数时,你正在浪费时间。

  • 找到第一个素数后,尝试将 max 减去该素数,直到它不再可整除。
  • 然后继续寻找下一个素数。
  • 并通过分解该素数来减小最大值。
  • 每次检查最大值是否等于当前素数。如果是这样,你就完成了。

假设您正确地找到了素数(我相信您是这样),请考虑以下几点:

primes = 2,3,5,7,11,13
max = 99

is 99 divisible by 2 - no, try next prime.
is 99 divisible y  3 -  yes
max = 33
is 33 divisble by 3  - yes 
max = 11
is 11 divisible by 3 - no
by 5 - no
by 7 - no
by 11 - hey, max is a prime! And it must be the largest because
it can't be reduced anymore.

如果您愿意,在找到 max 的每个素因子时,将其保存在一个列表中。

然后将列表中的所有值相乘,看看乘积是否 == 最大值。

这是你的代码

import java.util.ArrayList;

public class Test {
    public static void main(String[] args){
        long max = 600851475143L;
          // right here, reduce max by current prime (which starts at 2)

        for (long i = 3; i <= max; i += 2){
            boolean prime = true;
            for (long j = 3; j < Math.sqrt(i); j++){
                if (i % j == 0){
                    prime = false;
                    break;
                }
            }
            if (prime)  {
            // right here, reduce max by current prime

            }
        }
    }
}

【讨论】:

  • 对不起,我不完全理解您的解决方案。为什么不输出最低质数?
  • 注意。如果 max 有大素数作为因子。这将需要很长时间。如果 max 是素数。这将需要更长的时间。
  • 但是我仍然需要一个更有效的算法来获取初始素数列表,对吧?正如 cmets 对另一个答案所指出的那样,我现在使用的算法需要 7 天。
  • 您需要更高效的算法。但不一定要计算素数。那不是帐篷里的长杆。你试过我的建议了吗?
  • 对不起,我希望我不是迟钝,但我不是首先需要一个素数列表才能使用你的方法吗?
【解决方案2】:

您确定您的程序正在完成吗?我在下面添加了以下代码,看起来第一个 for 循环需要很长时间才能完成,这可能是您看不到任何输出的原因。要查看您的进度,请尝试添加如下打印语句:

import java.util.ArrayList;

public class Test {

    public static void main(String[] args){
        long max = 600851475143L;
        ArrayList<Long> primes = new ArrayList<Long>();
        primes.add((long) 2);
        boolean prime = true;
        for (long i = 3; i <= max; i += 2){
            if(i % 1000005 == 0)
                System.out.println("i = " + i);
            for (long j = 3; j < Math.sqrt(i); j++){
                if (i % j == 0){
                    prime = false;
                    break;
                }
            }
            if (prime) primes.add(i);
            else prime = true;
        }
        for (int i = primes.size() - 1; i >= 0; i--){
            if (max % primes.get(i) == 0){
                System.out.println(primes.get(i));
                return;
            }
        }
    }
}

【讨论】:

  • 这不是问题。
  • 这可能不是全部问题,但它是其中之一。你认为更大的问题是什么?
  • 找到所有这些素数需要很长时间。看看我的回答,看看你的想法?
  • @ap 是的,如果我们假设它每毫秒计算 1000 个数字,则需要将近 7 天
  • 小于N 的素数数量约为N/log(N),其中log 是自然对数。所以对于max = 600851475143,您需要计算和存储大约22,153,972,243 值。所以你(@ap)需要像我已经建议的那样从不同的角度来处理它。
猜你喜欢
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-30
相关资源
最近更新 更多