【问题标题】:Largest prime factor program takes aaaages - Java最大的素数程序需要 aaaages - Java
【发布时间】:2012-06-22 07:45:51
【问题描述】:

所以这是 Euler 项目的问题 3。不知道的人,我要找出最大的质因数600851475143。我有以下代码:

import java.lang.Math;
// 600851475143
public class LargestPrimeFactor {
    public static void main(String[] stuff) {
        long num = getLong("What number do you want to analyse? ");
        long[] primes = primeGenerator(num);
        long result = 0;
        for(int i = 0; i < primes.length; i++) {
            boolean modulo2 = num % primes[i] == 0;
            if(modulo2) {
                result = primes[i];
            }
        }
        System.out.println(result);
    }
    public static long[] primeGenerator(long limit) {
        int aindex = 0;
        long[] ps = new long[primeCount(limit)];
        for(long i = 2; i < limit + 1; i++) {
            if(primeCheck(i)) {
                ps[aindex] = i;
                aindex++;
            }
        }
        return ps;
    }

    public static boolean primeCheck(long num) {
        boolean r = false;
        if(num == 2 || num == 3) {
            return true;
        }
        else if(num == 1) {
            return false;
        }
        for(long i = 2; i < Math.sqrt(num); i++) {
            boolean modulo = num % i == 0;
            if(modulo) {
                r = false;
                break;
            }
            else if(Math.sqrt(num) < i + 1 && !modulo) {
                r = true;
                break;
            }
        }
        return r;
    }
    public static int primeCount(long limit) {
        int count = 0;
        if(limit == 1 || limit == 2) {
            return 0;
        }
        for(long i = 2; i <= limit; i++) {
            if(primeCheck(i)) {
                count++;
            }
        }
        return count;
    }
public static long getLong(String prompt) {
    System.out.print(prompt + " ");
    long mrlong = input.nextLong();
    input.nextLine();
    return mrlong;
}
}

但是当我用小于 600851475143 的东西(很多)测试程序时,比如 100000000,那么程序需要时间 - 事实上,到目前为止,100000000 已经花费了 20 分钟并且仍在继续。我显然在这里采用了错误的方法(是的,该程序 确实 工作,我用较小的数字进行了尝试)。任何人都可以提出一个不那么详尽的方法吗?

【问题讨论】:

  • 你读过一些关于素数的数学书吗?他们提供了更聪明的算法!
  • 您为什么不简单地尝试Sieve of Eratosthenes 来实现您的素数检查?
  • 为什么要生成最大为 num 的素数而不是 num 的平方根?如果该数不是素数,则它的因数必须小于或等于其平方根。另外,正如 Kazekage 所说,研究筛分。
  • @DavidConrad - 我是。 for(long i = 2; i &lt; Math.sqrt(num); i++)
  • @Bluefire 在 primeGenerator 和 primeCount 中,当您只需要生成不超过 limit 的平方根或大约 775 000 个的素数时,您会达到最多生成 6000 亿个素数的限制。 (您还应该将其更改为小于或等于限制的平方根,并且 primeCheck 可以变得更简单)。通过此更改,您的程序在我的笔记本电脑上运行时间为 1.2 秒。

标签: java prime-factoring


【解决方案1】:

试试这个..

public class LargestPrimeFactor{
public static int largestPrimeFactor(long number) {
    int i;
    for (i = 2; i <= number; i++) {
        if (number % i == 0) {
            number /= i;
            i--;
        }
    }
    return i;
}

/*  change according to ur requirement. 
public static long getLong(String prompt) {
    System.out.print(prompt + " ");
    long mrlong = input.nextLong();
    input.nextLine();
    return mrlong;
}
 */

public static void main(String[] args) {
    //long num = getLong("What number do you want to analyse? ");
    System.out.println(largestPrimeFactor(600851475143l));
}
}

【讨论】:

  • 此代码为示例中给出的数字返回 2,而正确答案是 6857
  • 我不知道你是怎么运行它的..因为我得到了 6857..你能再检查一下吗..
  • 这段代码效率低下。让我们举个例子(3*1000000000039)。仅在百万次迭代后才有可能产生正确的答案,但此代码将变为一百万和 39。请参阅stackoverflow.com/a/12046123/849891
【解决方案2】:
public static void main(String[] args) {

    long number = 600851475143L;

    long highestPrime = -1;
    for (long i = 2; i <= number; ++i) {
        if (number % i == 0) {
            highestPrime = i;
            number /= i;
            --i;
        }
    }

    System.out.println(highestPrime);
}

【讨论】:

    【解决方案3】:

    公共类 LargestPrimeFactor {

    public static boolean isPrime(long num){
        int count = 0;
        for(long i = 1; i<=num/2 ; i++){
            if(num % i==0){
                count++;
            }
        }
        if(count==1){
            return true;
        }
        return false;
    }
    
    public static String largestPrimeFactor(long num){
        String factor = "none";
        for(long i = 2; i<= num/2 ; i++){
            if(num % i==0 && isPrime(i)){
               factor = Long.toString(i); 
            }
        }
        return factor;     
    }
    public static void main(String[] args) {
        System.out.println(largestPrimeFactor(13195));
    }
    

    }

    【讨论】:

      【解决方案4】:

      我在 Project Euler 中完成了几十个挑战。有些问题可以通过蛮力解决(他们建议不要这样做),但其他问题需要“开箱即用”的思维。你无法通过蛮力解决这个问题。

      网络上有很多帮助可以引导您朝着正确的方向前进,例如: http://thetaoishere.blogspot.com.au/2008/05/largest-prime-factor-of-number.html

      【讨论】:

      • 剧透警告:我不小心发布了解决方案(用另一种语言)
      【解决方案5】:

      一个数可以拥有的素因数的数量总是小于该数的 sqrt,因此不需要遍历数 n 来找到它的最大素因数。

      查看此代码。

          public class LargestPrimeFactor {
              public static void main(String[] args) {
      
                  Scanner sc=new Scanner(System.in);
                  long num=sc.nextLong();
      
                  if(num>0 && num<=2)
                  {
                      System.out.println("largest prime is:-" + num);
                      System.exit(0);
                  }
      
                  int i=((Double)Math.sqrt(num)).intValue();
                  int j=3;
                  int x=0;
      
                  //used for looping through the j value which can also be a prime. for e.g in case of 100 we might get 9 as a divisor. we need to make sure divisor is also a prime number.
                  int z=0;
      //same function as j but for divisor
                  int y=3;
                  int max=2;
      //divisor is divisible
                  boolean flag=false;
      //we found prime factors
                  boolean found=false;
      
                  while(x<=i)
                  {
                      y=3;
                      flag=false;
      
                      if(num % j ==0)
                      {
                          if(j>max)
                          {
                              for(z=0;z<Math.sqrt(j);z++)
                              {
                                  if(j!=y && j % y==0)
                                  {
                                      flag=true;
                                  }
                                  y+=2;
                              }
                              if(!flag)
                              {
                                  found=true;
                                  max=j;
                              }
                          }
                      }
                      j+=2;
                      x++;
                  }
                  if(found){
                      System.out.println("The maximum prime is :- " + max);
                  }
                  else
                  {
                      System.out.println("The maximum prime is :- " + num);   
                  }
              }
          }
      

      【讨论】:

        【解决方案6】:

        改变

        for(long i = 2; i &lt;= limit; i++)

        // add the one for rounding errors in the sqrt function
        new_limit = sqrt(limit) + 1;
        // all even numbers are not prime 
        for(long i = 3; i <= new_limit; i+=2)
        {
        ...
        }
        

        以 1,000,000 为例,而不是迭代 1,000,000 次 这件事只需要进行大约 500 次迭代。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-25
          • 2017-01-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多