Euler#12项目的Java代码

Euler#12项目的Java代码,java,Java,我正在为Euler项目解决问题12,具体如下: 三角形数序列是通过添加自然数生成的。所以第七个三角形的数字是1+2+3+4+5+6+7=28。前十个任期为: 1、3、6、10、15、21、28、36、45、55 让我们列出前七个三角形数字的系数: 1:1 3:1,3 6:1,2,3,6 10:1,2,5,10 15:1,3,5,15 21:1,3,7,21 28:1,2,4,7,14,28 我们可以看到28是第一个有超过五个除数的三角形数 第一个有500个以上除数的三角形数的值是多少 这是我到目

我正在为Euler项目解决问题12,具体如下:

三角形数序列是通过添加自然数生成的。所以第七个三角形的数字是1+2+3+4+5+6+7=28。前十个任期为:

1、3、6、10、15、21、28、36、45、55

让我们列出前七个三角形数字的系数:

1:1

3:1,3

6:1,2,3,6

10:1,2,5,10

15:1,3,5,15

21:1,3,7,21

28:1,2,4,7,14,28

我们可以看到28是第一个有超过五个除数的三角形数

第一个有500个以上除数的三角形数的值是多少

这是我到目前为止的代码,但控制台在运行时不会返回任何内容:

public class Euler12 {
    public static void main (String[] args) {
        int i = 1;
        int x = 2;
        boolean found = false;
        while (!found) {
            if (divisors(i) > 500) {
                System.out.println(i);
                found = true;
            }
            else {
                i +=x;
                x++;
            }
        }
    }

    public static int divisors (int n) {
        int counter = 0;
        for (int i = 1; i <= n; i++) {
            if (n % i == 0) counter++;
        }
        return counter;
    }
}
公共类Euler12{
公共静态void main(字符串[]args){
int i=1;
int x=2;
布尔值=false;
而(!found){
if(除数(i)>500){
系统输出打印LN(i);
发现=真;
}
否则{
i+=x;
x++;
}
}
}
公共静态整数除数(整数n){
int计数器=0;

对于(int i=1;i,在运行程序之后,它似乎有一个非常长的运行时间,看看您的算法,它确实有(我以前做过这个问题)。您需要优化“除数”

扰流板


如果在运行程序后更改为(int i=1;i,似乎它的运行时间非常长,看看您的算法,它确实如此(我以前做过这个问题)。您需要优化“除数”

扰流板

如果更改为(int i=1;i
public类EulerProb12{
公共静态void main(字符串[]args){
int fib=0,count=1,i=1,incr=0;
而(增量
公共类EulerProb12{
公共静态void main(字符串[]args){
int fib=0,count=1,i=1,incr=0;

而(incr这里有两种选择:

1) 迭代所有三角形,如果
currentSum
(三角形编号)的除数超过
阈值,则停止

时间:1.79秒

public class P12 {

    final static int THRESHOLD = 500;

    public static void main(String[] args) {
        System.out.println(getTriangle());
    }

    public static long getTriangle() {
        int n = 1;
        long currentSum = 0;
        while (!hasOverXDivisors(currentSum, THRESHOLD)) {
            currentSum += n;
            n++;
        }
        return currentSum;
    }

    private static boolean hasOverXDivisors(long nr, int threshold) {
        if ( nr <= threshold ) {
            return false;
        }
        int divisors = 0;
        int i;
        int sqrt = (int) Math.sqrt(nr);
        for ( i = 1 ; i <= sqrt ; i++ ) {
            if ( nr % i == 0 ) {
                divisors+=2;           // E.g.: (2, n/2), (3, n/3)
            }
        }
        if ( sqrt*sqrt == nr ){        // it was counted twice
            divisors--;
        }
        if ( divisors > threshold ) {
            return true;
        }
        return false;
    }

}
public class P12 {

    final static int THRESHOLD_DIVISORS = 500;    

    public static void main(String[] args) {
        System.out.println(getTriangle(1));
    }

    public static long getTriangle(int n) {
        long numberOfDivisors = 0;
        long firstCoprime, secondCoprime;
        while (true) {
            if ( n % 2 == 0 ) {
                firstCoprime = getNumberOfDivisors(n/2);
                secondCoprime = getNumberOfDivisors(n+1);

            } else {
                firstCoprime = getNumberOfDivisors(n);
                secondCoprime = getNumberOfDivisors((n+1)/2);
            }           
            numberOfDivisors = firstCoprime * secondCoprime;
            if ( numberOfDivisors > THRESHOLD_DIVISORS ) {
                return n*(n+1)/2;
            }       
            n++;
        }
    }

    private static long getNumberOfDivisors(long nr) {
        int divisors = 0;
        int i;
        int sqrt = (int) Math.sqrt(nr);
        for ( i = 1 ; i <= sqrt ; i++ ) {
            if ( nr % i == 0 ) {
                divisors+=2;           // E.g.: (2, n/2), (3, n/3)
            }
        }
        if ( sqrt*sqrt == nr ){        // it was counted twice
            divisors--;
        }
        return divisors;
    }

}

我使用了一个整数作为
getTriangle()
方法的参数,以便更容易改进此方法。对于这种特殊情况,您可以决定从大于
1
的值开始。在这种情况下,您可以将时间减少至少3倍。

这里有两种选择:

1) 迭代所有三角形,如果
currentSum
(三角形编号)的除数超过
阈值,则停止

时间:1.79秒

public class P12 {

    final static int THRESHOLD = 500;

    public static void main(String[] args) {
        System.out.println(getTriangle());
    }

    public static long getTriangle() {
        int n = 1;
        long currentSum = 0;
        while (!hasOverXDivisors(currentSum, THRESHOLD)) {
            currentSum += n;
            n++;
        }
        return currentSum;
    }

    private static boolean hasOverXDivisors(long nr, int threshold) {
        if ( nr <= threshold ) {
            return false;
        }
        int divisors = 0;
        int i;
        int sqrt = (int) Math.sqrt(nr);
        for ( i = 1 ; i <= sqrt ; i++ ) {
            if ( nr % i == 0 ) {
                divisors+=2;           // E.g.: (2, n/2), (3, n/3)
            }
        }
        if ( sqrt*sqrt == nr ){        // it was counted twice
            divisors--;
        }
        if ( divisors > threshold ) {
            return true;
        }
        return false;
    }

}
public class P12 {

    final static int THRESHOLD_DIVISORS = 500;    

    public static void main(String[] args) {
        System.out.println(getTriangle(1));
    }

    public static long getTriangle(int n) {
        long numberOfDivisors = 0;
        long firstCoprime, secondCoprime;
        while (true) {
            if ( n % 2 == 0 ) {
                firstCoprime = getNumberOfDivisors(n/2);
                secondCoprime = getNumberOfDivisors(n+1);

            } else {
                firstCoprime = getNumberOfDivisors(n);
                secondCoprime = getNumberOfDivisors((n+1)/2);
            }           
            numberOfDivisors = firstCoprime * secondCoprime;
            if ( numberOfDivisors > THRESHOLD_DIVISORS ) {
                return n*(n+1)/2;
            }       
            n++;
        }
    }

    private static long getNumberOfDivisors(long nr) {
        int divisors = 0;
        int i;
        int sqrt = (int) Math.sqrt(nr);
        for ( i = 1 ; i <= sqrt ; i++ ) {
            if ( nr % i == 0 ) {
                divisors+=2;           // E.g.: (2, n/2), (3, n/3)
            }
        }
        if ( sqrt*sqrt == nr ){        // it was counted twice
            divisors--;
        }
        return divisors;
    }

}
我使用了一个整数作为
getTriangle()
方法的参数,以便于改进此方法。对于这种特殊情况,您可以决定从大于
1
的值开始。在这种情况下,您可以将时间减少至少3倍。

使用“素因式分解”将使您的
除数()
更快更好

尝试以下函数,
getNumberOfDivisors()
,而不是您的
除数()

公共静态长getNumberOfDivisors(长n){
int-ret=1;
长因子=2;
而(factor)使用“素因子分解”将使您的除数()更快更好

尝试以下函数,
getNumberOfDivisors()
,而不是您的
除数()

公共静态长getNumberOfDivisors(长n){
int-ret=1;
长因子=2;

虽然(因子如果你打印出每个i和相应的除数,跟踪就简单多了。你确定它不慢并且还在运行吗?如果你打印出每个i和相应的除数,跟踪就简单多了。你确定它不慢并且还在运行吗?这确实减少了执行时间,但并不能给出正确的答案。如果使用上述修复,则需要计算每个除数的另一半。将计数器增加2。(计数器+=2;)@Will.Beninger您只需要求出数字的平方根,然后在最后将其乘以2。这确实减少了执行时间,但并不能给出正确的答案。如果使用上述修复,则需要计算每个除数的另一半。将计数器增加2。(计数器+=2;)@你只需要求出这个数字的平方根,然后在最后乘以2。