【问题标题】:Project Euler #10, java [duplicate]欧拉项目#10,java [重复]
【发布时间】:2010-08-03 18:16:17
【问题描述】:

可能重复:
Project Euler, Problem 10 java solution not working

所以,我正在尝试用 Java 解决 Project Euler Problem 10,但我得到的答案不是正确的。这是我的代码:

public class Problem10 {
public static void main(String[] args)
{
    long sum =0;
    for(int i =3;i<2000000;i+=2)
    {
        if(isPrime(i))
        {
            sum+=i;
        }
    }
    System.out.println(sum);
}

public static boolean isPrime(int n)
{
    boolean prime = true;
    if (n<2) return false;
    if (n==2) return true;
    if (n%2==0) return false;
    for (int i = 3; i<=Math.sqrt(n);i+=2)
    {
        if (n%i==0)
        {
            prime=false;
            break;
        }
    }
    return prime;
}
}

打印出 142913828920,Euler 告诉我的项目是错误的。

有什么想法吗?

(另外,我知道我寻找素数的方法非常低效。)

【问题讨论】:

  • 这种方法并不是非常效率低下。在 Haskell 中,它是 2 : [n | n&lt;-[3,5..], all ((&gt; 0).rem n) [3,5..floor(sqrt(fromIntegral n))]] - 奇数的最小试除法。以下 非常低效,并且流行sieve [2..] where sieve (x:xs) = x : sieve [n | n &lt;- xs, rem n x &gt; 0] - 过度试除以素数。 [n | n&lt;-[2..], all ((&gt; 0).rem n) [2..n-1]] 更慢但也很受欢迎 - 所有数字的过度试验划分。 [n | n&lt;-[2..], not $ elem n [j*k | j&lt;-[1..n-1], k&lt;-[1..n-1]]] 是冠军 - 我在 SO 上看到它(在 Java IIRC 中)!

标签: java primes


【解决方案1】:
for(int i =3;i<2000000;i+=2)

2 是素数。

【讨论】:

  • 如果你在上面注意到,我有 if (n==2) return true;
  • 但在 main 中,您的循环从 3 开始。
  • 但是你从 3 开始,所以 n 永远不会等于 2
【解决方案2】:

您可以通过仅划分素数来稍微加快代码速度。例如,你可以通过尝试将 35 除以 2、3、5 来知道它不是质数。无需尝试 4。诀窍是,任何时候找到质数时,将其保存在列表中或一个向量。在你的 isPrime 函数中,只需迭代列表直到它达到 sqrt(n) 而不是 3..sqrt(n) 之间的每个值。

【讨论】:

  • 这会占用大量内存
  • @amir: 不是真的......有
  • 在任何情况下,代码都只需不到 5 秒的时间就可以按原样运行。真的不需要优化。
【解决方案3】:

您可以使用 Sieve 进一步加速您的代码。

【讨论】:

    【解决方案4】:

    我发现以下方法非常有效,当我检查一个数字是否为素数时,我只将该数字除以先前找到的素数并且低于 n 的平方根。无需检查 n 平方根以下的所有数字。而且只需要一秒多!!

    public class Problem10 {
    
        private static List<Long> listOfPrimes = new ArrayList<Long>();
    
        public static void main(String args[]) {
    
            long count = 0;
            for (long i = 2; i < 2000000; i++) {
                if (isPrime(i)) {
                    count += i;
                    System.out.print(i + " ");
                }
                if (i % 1000 == 0) {
                    System.out.println();
                }
            }
    
            System.out.println("\nTotal " + count);
    
        }
    
        private static boolean isPrime(long n) {
    
            String strFromN = new Long(n).toString();
            if ((strFromN.length() != 1) && (strFromN.endsWith("2") || strFromN.endsWith("4") || strFromN.endsWith("5") || strFromN.endsWith("6") || strFromN.endsWith("8"))) {
                return false;
            }
    
            for (Long num : listOfPrimes) {
                if (num > Math.sqrt(n)) {
                    break;
                }
                if (n % num.longValue() == 0) {
                    return false;
                }
            }
    
    
            listOfPrimes.add(new Long(n));
            return true;
        }
    }
    

    【讨论】:

    • 不需要测试2以上的偶数;它已被称为素数:将 long count = 0; for (long i = 2; i &lt; 2000000; i++) { 替换为 long count = 2; for (long i = 3; i &lt; 2000000; i+=2) {。所以现在不需要字符串转换了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 2014-03-08
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多