Euler#3项目在Java中花费了很长时间

Euler#3项目在Java中花费了很长时间,java,primes,prime-factoring,Java,Primes,Prime Factoring,Euler项目的问题3是: 13195的主要因子为5、7、13和29 数字600851475143中最大的素因子是什么 我的解决方案需要很长时间。我认为我得到了正确的实施;然而,当用大数字进行测试时,我无法看到结果。它永远运行。我想知道我的算法是否有问题: public class LargestPrimeFactor3 { public static void main(String[] args) { long start, end, totalTime;

Euler项目的问题3是:

13195的主要因子为5、7、13和29

数字600851475143中最大的素因子是什么

我的解决方案需要很长时间。我认为我得到了正确的实施;然而,当用大数字进行测试时,我无法看到结果。它永远运行。我想知道我的算法是否有问题:

public class LargestPrimeFactor3 {

    public static void main(String[] args) {
        long start, end, totalTime;
        long num = 600851475143L;
        long pFactor = 0;

        start = System.currentTimeMillis();

        for(int i = 2; i < num; i++) {
            if(isPrime(i)) {                
                if(num % i == 0) {
                    pFactor = i;                        
                }
            }
        }

        end = System.currentTimeMillis();
        totalTime = end - start;
        System.out.println(pFactor + " Time: "+totalTime);
    }

    static boolean isPrime(long n) {

        for(int i = 2; i < n; i++) {
            if(n % i == 0) {
                return false;
            }
        }        
        return true;
    }     
}
public类最大的primefactor3{
公共静态void main(字符串[]args){
长起点、终点、总时间;
长数=600851475143L;
长pFactor=0;
start=System.currentTimeMillis();
for(int i=2;i
有两件事可以提高性能:

static boolean isPrime(long n)
{
    for(int i = 2; i <= sqrt(n); i++)  // if n = a * b, then either a or b must be <= sqrt(n).
    {
        if(n % i == 0)
        {
            return false;
        }
    }        
    return true;
}  
这里仍然有可以改进的地方,但这需要你去发现。考虑修改
num
。享受Euler项目的乐趣:)

公共哈希集distinctPrimeFactors(int n)//疯狂快速素因子生成器
{
HashSet factors=新的HashSet();
int lastres=n;
如果(n==1)
{
增加(1);
回报因素;
}
while(true)
{
如果(lastres==1)
打破
int c=2;
while(true)
{
如果(lastres%c==0)
打破
C++;
}
增加(c);
lastres/=c;
}
回报因素;
}

如果您想为一个数字快速生成不同的素数因子,请使用此方法,该方法可使该数字在每次迭代中变小。您可以将int改为long,它应该适合您。

虽然不是用Java编写的,但我认为您可能可以理解以下内容。基本上,只需测试奇数因子和一个数的平方根就可以减少迭代次数。下面是一个蛮力方法,它在C#中给出了一个即时结果

static bool OddIsPrime(long oddvalue)//测试一个奇数>=3
{
//只测试奇数除数。

对于(长i=3;i,这里是通过尝试除法进行整数因子分解的伪代码:

define factors(n)

    z = 2

    while (z * z <= n)

        if (n % z == 0)
            output z
            n /= z

        else
            z++

    output n
定义因子(n)
z=2
而(z*z您应该按找到的每个因子进行除法。然后,当我们按升序枚举可能的因子时,无需测试它们的素性(因此找到的因子不能是复合的,它的因子将被除法)。您的代码将变成:

class LargestPrimeFactor4 {

    public static void main(String[] args) {
        long start, end, totalTime;
        long num = 600851475143L;   // odd value is not divided by any even
        long pFactor = 1L;

        start = System.currentTimeMillis();

        for(long i = 3L; i <= num / i; ) 
        {
            if( num % i == 0 ) {
                pFactor = i;
                num = num / i;
            }
            else {
                i += 2;
            }
        }
        if( pFactor < num ) { pFactor = num; }

        end = System.currentTimeMillis();
        totalTime = end - start;
        System.out.println( pFactor + " Time: " + totalTime);
    }
}
class LargestPrimeFactor4{
公共静态void main(字符串[]args){
长起点、终点、总时间;
long num=600851475143L;//奇数不除以任何偶数
长pFactor=1L;
start=System.currentTimeMillis();
对于(长i=3L;i
public class LargestPrimeFactor){
静态布尔isPrime(长n){

对于(长i=2;i您可以对数字进行素因子分解,然后最大的素因子就是答案:

import java.util.ArrayList;
import java.util.Collections;

public class PrimeFactorization {

    /* returns true if parameter n is a prime number, 
         false if composite or neither */
    public static boolean isPrime(long n) {
        if (n < 2) return false;
        else if (n == 2) return true;
        for (int i = 2; i < Math.pow(n, 0.5) + 1; i++)
            if (n % i == 0)
                return false;
        return true;
    }

    /* returns smallest factor of parameter n */
    public static long findSmallestFactor(long n) {
        int factor = 2; // start at lowest possible factor
        while (n % factor != 0) { // go until factor is a factor
            factor++; // test the next factor
        }
        return factor;
    }

    /* reduces the parameter n into a product of only prime numbers
       and returns a list of those prime number factors */
    public static ArrayList<Long> primeFactorization(long n) {

        ArrayList<Long> primes = new ArrayList<Long>();
          // list of prime factors in the prime factorization
        long largestFactor = n / findSmallestFactor(n);    

        long i = 2;
        while (i <= largestFactor) { 
          // for all possible prime factors 
          // (2 - largest factor of the number being reduced)

            if (isPrime(i) && n % i == 0) { 
                // if this value is prime and the number is divisible by it

                primes.add(i); // add that prime factor to the list
                n /= i; // divide out that prime factor from the number 
                        // to start reducing the new number
                largestFactor /= i; // divide out that prime factor 
                       // from the largest factor to get the largest 
                       // factor of the new number
                i = 2; // reset the prime factor test
            } else {
                i++; // increment the factor test
            }
        }

        primes.add(n); // add the last prime number that could not be factored
        Collections.sort(primes);
        return primes;
    }
}
import java.util.ArrayList;
导入java.util.Collections;
公共类素因子分解{
/*如果参数n是质数,则返回true,
如果为复合或两者都不是,则为false*/
公共静态布尔iPrime(长n){
如果(n<2)返回false;
如果(n==2),则返回true;
对于(inti=2;i而(i这一款非常好用!!

public class Puzzle3 {
public static void main(String ar[])
{
    Long i=new Long("1");
    Long p=new Long("600851475143");
    Long f=new Long("1");
    while(p>=i)
    {
        if(p%i==0)
        {
            f=i;
            p=p/i;
            int x=1;
            i=(long)x;
        }
        i=i+2;
    }
    System.out.println(f);
}

}

这不是完美的解决方案,但它适用于600851475143

public static void main(String[] args) {
    long number= 600851475143L;
    int rootOfNumber = (int)Math.sqrt(number)+10;
    for(int i = rootOfNumber; i > 2; i--) {
        if(number % i == 0) {
            if(psudoprime(i)) {
                System.out.println(i);
                break;
            }
        }
    }

}

public static boolean psudoprime(int num) {
    for(int i = 2; i < 100; i++) {
        if(num % i == 0) {
            return false;
        }
    }
    return true;
}
publicstaticvoidmain(字符串[]args){
长编号=600851475143L;
int rootOfNumber=(int)Math.sqrt(number)+10;
对于(int i=根数;i>2;i--){
如果(编号%i==0){
if(伪主(i)){
系统输出打印LN(i);
打破
}
}
}
}
公共静态布尔值psudoprime(int num){
对于(int i=2;i<100;i++){
如果(num%i==0){
返回false;
}
}
返回true;
}

我将从优化您的
isPrime
循环开始。只需迭代到
I>sqrt(n)
。要添加到Blender,您还可以在for循环之前检查n%2==true..并以I=3开始for循环,然后迭代2(I+=2).A sieve会更快。如果您使用Java,还可以使用from
biginger
类而不是
for(int i=2;i
在您的
main
方法中。如果您真的想让它运行得更快,请尝试C/C++。它在不到一秒钟的时间内为我运行,并且没有下面建议的优化。作为旁注,project euler是关于优化的,而不仅仅是蛮力。有许多问题在任何时间内都无法使用“简单”解决方案解决(在任何语言中)。你需要弄清楚逻辑上的“捷径”是什么
public class LargestPrimeFactor {
    static boolean isPrime(long n){
        for(long i=2;i<=n/2;i++){
            if(n%i==0){
                return false;                                               
            }
        }
        return true;    
    }

    static long LargestPrimeFact(long n){
        long largestPrime=0;
        for(long i=2;i<Math.sqrt(n)/2;i++){
            if(n%i==0){
                if(isPrime(i)){
                    largestPrime=i;
                }
                }                                       
            }
        return largestPrime;
    }
    public static void main(String args[]) {
        System.out.println (LargestPrimeFact(600851475143L));
    }
}
import java.util.ArrayList;
import java.util.Collections;

public class PrimeFactorization {

    /* returns true if parameter n is a prime number, 
         false if composite or neither */
    public static boolean isPrime(long n) {
        if (n < 2) return false;
        else if (n == 2) return true;
        for (int i = 2; i < Math.pow(n, 0.5) + 1; i++)
            if (n % i == 0)
                return false;
        return true;
    }

    /* returns smallest factor of parameter n */
    public static long findSmallestFactor(long n) {
        int factor = 2; // start at lowest possible factor
        while (n % factor != 0) { // go until factor is a factor
            factor++; // test the next factor
        }
        return factor;
    }

    /* reduces the parameter n into a product of only prime numbers
       and returns a list of those prime number factors */
    public static ArrayList<Long> primeFactorization(long n) {

        ArrayList<Long> primes = new ArrayList<Long>();
          // list of prime factors in the prime factorization
        long largestFactor = n / findSmallestFactor(n);    

        long i = 2;
        while (i <= largestFactor) { 
          // for all possible prime factors 
          // (2 - largest factor of the number being reduced)

            if (isPrime(i) && n % i == 0) { 
                // if this value is prime and the number is divisible by it

                primes.add(i); // add that prime factor to the list
                n /= i; // divide out that prime factor from the number 
                        // to start reducing the new number
                largestFactor /= i; // divide out that prime factor 
                       // from the largest factor to get the largest 
                       // factor of the new number
                i = 2; // reset the prime factor test
            } else {
                i++; // increment the factor test
            }
        }

        primes.add(n); // add the last prime number that could not be factored
        Collections.sort(primes);
        return primes;
    }
}
ArrayList<Long> primes = PrimeFactorization.primeFactorization(600851475143L);
System.out.println(primes.get(primes.size() - 1));
public class Puzzle3 {
public static void main(String ar[])
{
    Long i=new Long("1");
    Long p=new Long("600851475143");
    Long f=new Long("1");
    while(p>=i)
    {
        if(p%i==0)
        {
            f=i;
            p=p/i;
            int x=1;
            i=(long)x;
        }
        i=i+2;
    }
    System.out.println(f);
}
public static void main(String[] args) {
    long number= 600851475143L;
    int rootOfNumber = (int)Math.sqrt(number)+10;
    for(int i = rootOfNumber; i > 2; i--) {
        if(number % i == 0) {
            if(psudoprime(i)) {
                System.out.println(i);
                break;
            }
        }
    }

}

public static boolean psudoprime(int num) {
    for(int i = 2; i < 100; i++) {
        if(num % i == 0) {
            return false;
        }
    }
    return true;
}