Java 找到一个非常大的数字

Java 找到一个非常大的数字,java,Java,所以,我试图找到最大的素因子600851475143。我有一个简单的方法,可以找到目前最大的一个: private static void findPrimeFactors(long num) { ArrayList<Long> list = new ArrayList<Long>(); for (long i = 1; i <= num; i++) { int lol = 0; for

所以,我试图找到最大的素因子600851475143。我有一个简单的方法,可以找到目前最大的一个:

private static void findPrimeFactors(long num) {
        ArrayList<Long> list = new ArrayList<Long>();
        for (long i = 1; i <= num; i++) {
            int lol = 0;
            for (int a = 1; a < i; a++) {
                if (i % a == 0) {
                    lol++;
                }
            }
            if (lol < 2) {
                if (!list.isEmpty())
                    list.remove(list.size() - 1);
                list.add(i);
            }
        }
        System.out.println(list.get(list.size() - 1));
    }
和20000:

19997
Done in 1774.0 milliseconds (1.774 seconds) (177.3702774 nano seconds)
正如你所看到的,在一个更大的数字中找到它需要相当长的时间。现在我应该在600851475143中找到我要找的号码,所以我可以说这需要一段时间。我想知道他们是否有更快的计算方法?这是我的全部代码:

import java.util.ArrayList;


public class Main {

    public static void main(String[] args) {
        try {
        long num = 600851475143L;
        long time = System.currentTimeMillis();
        long timeNano = System.nanoTime();

        findPrimeFactors(20000);

        double finishTime = System.currentTimeMillis() - time;
        double finishTimeNano = System.nanoTime() - timeNano;
        System.out.println("Done in " + finishTime + " milliseconds (" + ((finishTime) / 1000) + " seconds)" + " (" + finishTimeNano / 10000000 + " nano seconds)");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void findPrimeFactors(long num) {
        ArrayList<Long> list = new ArrayList<Long>();
        for (long i = 1; i <= num; i++) {
            int lol = 0;
            for (int a = 1; a < i; a++) {
                if (i % a == 0) {
                    lol++;
                }
            }
            if (lol < 2) {
                if (!list.isEmpty())
                    list.remove(list.size() - 1);
                list.add(i);
            }
        }
        System.out.println(list.get(list.size() - 1));
    }
}
import java.util.ArrayList;
公共班机{
公共静态void main(字符串[]args){
试一试{
长数=600851475143L;
长时间=System.currentTimeMillis();
long-timeNano=System.nanoTime();
findPrimeFactors(20000);
double finishTime=System.currentTimeMillis()-时间;
double finishTimeNano=System.nanoTime()-timeNano;
System.out.println(“完成时间为”+finishTime+“毫秒”(+((finishTime)/1000)+“秒)”+“(+finishTimeNano/10000000+“纳秒”);
}捕获(例外e){
e、 printStackTrace();
}
}
私有静态void findPrimeFactors(long num){
ArrayList=新建ArrayList();

对于(long i=1;i如果您正在寻找最大的因素,可以从最大的数字开始。类似这样的内容(未测试的代码):

私有静态void findPrimeFactors(long num){
龙我;
布尔候选;
对于(i=num;i>1;i--){
//我被选为首要因素
候选者=真;

对于(int a=2;候选者和&a提示,请加快:

  • 您正在尝试边修改ArrayList,每次修改ArrayList都需要O(n)个时间。如果确实需要修改列表,请查看使用链接列表
  • 你不需要测试所有的数字,只需要测试素数

首先你必须了解的是,你的任务本质上是“找到一个大数的素数因子”。如果你知道怎么做,你可以将你的大数除以找到的因子,然后进行一次循环

…但我很遗憾地告诉你,没有已知的算法可以在多项式时间内找到Laaaarge数的素因子。实际上,这是许多密码系统(例如著名的RSA)的基础

然而,现在600851475143这样的数字可以很快被分解。有很多算法可以做到这一点,但你必须学习一些数学才能理解它们


对于这个数字,我可以告诉您600851475143=71*839*1471*6857。

您需要一个更好的算法。下面是一个简单的试用除法实现:

function factors(n)
  f, fs := 2, []
  while f * f <= n
    while n % f == 0
      append f to fs
      n := n / f
    f := f + 1
  if n > 1 append n to fs
  return fs
功能因子(n)
f、 fs:=2,[]
而f*f 1将n附加到fs
返回fs
我将让您使用适当的数据类型将伪代码转换为您最喜欢的编程语言。请注意,600851475143太大,无法存储在32位整数中,这是问题的一部分乐趣


如果你对解决涉及质数的Euler项目问题感兴趣,我谦虚地在我的博客上推荐这篇文章。

这些质数<20000除以你的大数吗?这会很好地分解它。我想你可以看看这个。希望这能帮上忙。我现在正在测试它,真的需要一段时间……猜猜真的需要质数列表才能更快地工作…即使只使用质数因子,这也需要很长时间。顺便说一句,答案是600851475067。这是第23038900221个质数。在这里找到它:您可以在
num
的swuare根启动
candidate
循环,从而节省大量时间。此外,您还可以使用计算素数直到600851475143的平方根以节省更多的时间并将它们存储在
集合中而不是
列表中
+1来解决密码系统就是基于这个问题,我也试过了!它工作得快多了,但仍然需要一段时间才能达到我想要的。答案应该是立即的。如果不是的话,您的实现有问题。
private static void findPrimeFactors(long num) {
  long i;
  boolean candidate;
  for (i=num; i>1; i--){
    // i is candidate to be prime factor
    candidate=true;
    for (int a=2; candidate && a<i; a++){
      if (i % a == 0) candidate=false; // i is not prime.
    }
    if (candidate) break;
  }

  System.out.println(i);

}
import java.util.*;

public class PrimeFinder {

  private static List<Long> finder (Long max){
    List<Long> list=new ArrayList<Long>();
    Long maxPrime=2L;
    Long i;
    boolean candidate=true;
    for (i=2L;i<max;i++){
      candidate=true;
      for (Long prime:list){
        if (i % prime==0) {candidate=false;break;}
      }
      if (candidate){
        list.add(i);
        System.out.println(i+" "+list.size());
        maxPrime=i;
      }
    }

    System.out.println(maxPrime);
    return list;

  }

  public static void main(String[] argv){
    finder(600851475143L);
  }
}
function factors(n)
  f, fs := 2, []
  while f * f <= n
    while n % f == 0
      append f to fs
      n := n / f
    f := f + 1
  if n > 1 append n to fs
  return fs