Euler项目的错误答案50

时间:2013-04-03 00:59:42

标签: java algorithm numbers

我正在尝试项目Euler的问题50。

  

素数41,可以写成六个连续素数的总和:

     

41 = 2 + 3 + 5 + 7 + 11 + 13这是连续的最长和   素数增加到低于一百的素数。最长的一笔   连续素数低于一千,加上素数,包含   21个术语,等于953.哪个素数低于一百万,可以   写作最连续素数的总和?

这是我的代码:

    public class consPrime
    {
        static int checker(int ar[],int num,int index) //returns no.of consecutive
        {                                              //primes for the given num  
            while(true)
        {

        int temp=num;

        for(int i=index;i>=0;i--)
        {
            temp=temp-ar[i];

            if(temp==0)
            {
                return (index-i+1);
            }               
        }           
        index--;
        if(index==0)
        return 0;           
        }
    }

    public static void main(String args[])
    {               
        int n=100000;
        int ar[]=new int[n];
        int total=0;int flag;

        for(int i=2;i<1000000;i++)   //Generates an array of primes below 1 million
        {
            flag=1;

            for(int j=2;j<=Math.sqrt(i);j++)
            {
                if(i%j==0)
                {
                    flag=0;
                    break;
                }                   
            }
            if(flag==1)
            {
                ar[total]=i;
                total++;
            }               
        }

        int m=0;
        int Big=0;

        for(int i=total;i>=0;i--) //Prints the current answer with no.of prime
        {
            m=checker(ar,ar[i],i-1);
            if(Big<=m)
            {Big=m;
                System.out.println(ar[i]+"     "+Big);
            }
        }           
    }       
}

基本上它只是创建一个高达1000000的所有质数的向量,然后循环遍历它们找到正确的答案。答案是997651,计数应该是543,但我的程序分别输出990707和75175。什么可能是错的?

2 个答案:

答案 0 :(得分:2)

几个大问题:

  1. 首先出现一些小问题:学会正确缩进代码,学会使用正确的命名约定。在Java中,变量名称使用camelCasing,而类型名称使用PascalCasing。

  2. 你的逻辑中有很多问题:你通过素数数组循环,直到你达到零或直到通过数组中的所有数字循环。但请注意,整数有下溢/溢出。 “temp”可能会继续扣除并变为负数并变为正数,因此依此类推并且为零。然而,这不是正确的答案

  3. 您只是试图找到以索引为1结尾的连续数字。例如,要检查索引10处的素数,您将从索引9向后查找连续的素数。然而,连续的总和很少达到目标数量(实际上几乎从不,除了5)包含“先前”的素数。整个逻辑完全是错误的。

  4. 更不用说您为检查者传递的错误参数,用户评论@ pm-77-1

答案 1 :(得分:0)

这是另一种采用 43 ms 的方法。

它基于以下方法:

1)使用筛子生成素数&lt; = 1000000

2)它通过所有数字在 O(n 2 中迭代,并计算连续的素数。第一个循环更改序列的第一个元素,第二个循环从该位置开始,并将它们添加到总和中。如果总和是素数,它由最大数量的素数组成,而不是保留在变量中。

import java.util.ArrayList;
import java.util.List;

public class P50 {

    private final static int N = 1_000_000;

    public static void main(String[] args) {
        boolean primes[] = generatePrimes(N);
        List<Integer> primeIntegers = new ArrayList<Integer>();
        for (int i = 0; i < primes.length; i++) {
            if (primes[i]) {
                primeIntegers.add(i);
            }
        }
        int count = 0;
        int sum = 0;
        int finalSum = 0;
        int finalCount = 0;
        int totalPrimes = primeIntegers.size();
        for (int start = 0; start < totalPrimes; start++) {
            sum = 0;
            count = 0;
            for (int current = start; current < totalPrimes; current++) {
                int actual = primeIntegers.get(current);
                sum += actual;
                if ( sum >= N ) {
                    break;
                }
                if ( primes[sum] ) {
                    if ( count > finalCount ) {
                        finalCount = count;
                        finalSum = sum;
                    }
                }
                count++;
            }
        }
        System.out.println(finalSum);
    }

    private static boolean[] generatePrimes(int n) {
        boolean primes[] = new boolean[n];
        for (int i = 0; i < n; i++) {
            primes[i] = true;
        }
        primes[0] = false;
        primes[1] = false;
        // i = step
        for (int i = 2; i * i < n; i++) {
            if (primes[i]) {
                for (int j = i * i; j < n; j += i) {
                    primes[j] = false;
                }
            }
        }
        return primes;
    }

}