Java程序需要花费很长时间才能运行大量数据

Java程序需要花费很长时间才能运行大量数据,java,Java,我正在编写一个Java程序来计算一个大数中的最大素数因子。但是我对程序的复杂性有一个问题,我不知道是什么导致程序永远运行在大的数字上,它在小的数字上运行良好 我的工作如下: import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; public class Largest_prime_factor { public static void main(String[] args) {

我正在编写一个Java程序来计算一个大数中的最大素数因子。但是我对程序的复杂性有一个问题,我不知道是什么导致程序永远运行在大的数字上,它在小的数字上运行良好

我的工作如下:

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

public class Largest_prime_factor {

public static void main(String[] args) 
{
    //ArrayList primesArray = new ArrayList();
    ArrayList factorArray = new ArrayList();
    long largest = 1;
    long number = 600851475143L ;
    long i, j, k;

    //the array list factorArray will have all factors of number
    for (i = 2; i < number; i++)
    {
        if( number % i == 0)
        {
            factorArray.add(i);

        }
    }
for (i = 2; i < number; i++)
        {
         if (!isPrime(i))
         {
             factorArray.remove(i);
             System.out.println(factorArray);
         }
        }


        System.out.println(Collections.max(factorArray));
    }
因此,代码的下一部分如下所示:

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

public class Largest_prime_factor {

public static void main(String[] args) 
{
    //ArrayList primesArray = new ArrayList();
    ArrayList factorArray = new ArrayList();
    long largest = 1;
    long number = 600851475143L ;
    long i, j, k;

    //the array list factorArray will have all factors of number
    for (i = 2; i < number; i++)
    {
        if( number % i == 0)
        {
            factorArray.add(i);

        }
    }
for (i = 2; i < number; i++)
        {
         if (!isPrime(i))
         {
             factorArray.remove(i);
             System.out.println(factorArray);
         }
        }


        System.out.println(Collections.max(factorArray));
    }
(i=2;i { 如果(!iPrime(i)) { 去除(i); System.out.println(FactoryArray); } } System.out.println(Collections.max(factorArray)); } 最后一行打印的factorArray数量最大,这就是我要寻找的

    public static boolean isPrime(long n) 
    {
        if(n > 2 && (n & 1) == 0)
           return false;
        for(int i = 3; i * i <= n; i += 2)
            if (n % i == 0) 
                return false;
        return true;
    }   

}
public静态布尔值isPrime(长n)
{
如果(n>2&(n&1)==0)
返回false;
对于(int i=3;i*i)

这是一个巨大的数字,你要循环两次。试着每10000或100000次计数(如果我打印了%10000(i)),你就会知道它的速度有多快。

你循环了600851475143个数字

long number = 600851475143L ;
for (i = 2; i < number; i++)
long number=600851475143L;
对于(i=2;i
即使我们假设每次迭代只需要很短的时间(只有1微秒),但在循环完成之前仍需要几天的时间

为了使该程序运行得更快,您需要优化主要查找逻辑

将迭代次数减少到合理数目的一种方法是循环直到该数目的平方根

for (i = 2; i < Math.sqrt(number); i++)
for(i=2;i

for(i=2;i*i
计算600851475143L的基本因子应不到一毫秒(使用的算法并非完全无效)。您的代码目前缺少的主要部分包括:

边框应该是sqrt(数字),而不是数字。
应在while循环中检查当前值(为了防止非素数因子添加到列表中,减少要检查的范围)。
找到系数后,应将最大值(以及边框)减小到数字/系数

进一步的改进是可能的,例如只迭代非偶数(或只迭代不是2和3的倍数的数)等

codereview()上相同问题的示例实现:

public静态长参数(
最终长输入){
////
如果(输入<2)
抛出新的IllegalArgumentException();
长n=输入;
longlast=0;
对于(;(n&1)==0;n>>=1)
last=2;
对于(;n%3==0;n/=3)
last=3;

对于(long v=5,add=2,border=(long)Math.sqrt(n);v一个可能的解决方案是只测试小于大数的素数是否除以它。 所以我查了一下

        for (i=2; i < number; i++)
        {
            if(isPrime(i))
            {
                 if( number % i == 0)
                 {
                     factorArray.add(i);                    
                 }
            }   
        }
(i=2;i { 如果(i) { 如果(编号%i==0) { 添加(i); } } }
所以这里我只除以素数,而不是除以所有小于600851475143的数。
但这仍然不是很快,需要对算法进行完全修改以获得最佳算法。

@Balkrishna Rawool建议是正确的方法。为此,我建议更改迭代如下:For(I=3;I可能更多的是内存问题,因为您似乎将整数放入了一个列表中。您是否检查了内存的演变情况?以及GC活动?嗯,600851475143是一个非常大的数字。如果您的“较小的数字”是600851475(这本身已经是一个非常大的数字),那么对于这个较大的数字,需要花费至少1000倍的时间。您期望的是什么?您的算法必须是O(N)或更糟糕的O(N^2)您可以做的一个改进是使用
HashSet
而不是
ArrayList
。但是,即使每个循环迭代只需要纳秒级,程序也需要很多小时。祝贺您!您刚刚发现了现代密码学一个分支的基础。素数分解是一个已知的难题,而t fact用于在多个加密系统中创建公钥/私钥对。如果你要解决这个问题,你将一举摧毁密码理论的一大部分,并可能解决现代计算的圣杯,即P=NP问题。也就是说,这不会发生。我试过使用factoraray.size()相反,但非素数并没有从列表中删除。@Ouissalbenamer,我想你误解了我的意思。这不是你在循环中所做的,你试图访问万亿个数字,这将需要很长时间。没有办法“修复”除非你改进寻找素数的算法。
for (i = 2; i*i < number; i++)
public static long largestPrimeFactor(
        final long input) {
    ////
    if (input < 2)
        throw new IllegalArgumentException();

    long n = input;
    long last = 0;
    for (; (n & 1) == 0; n >>= 1)
        last = 2;
    for (; n % 3 == 0; n /= 3)
        last = 3;
    for (long v = 5, add = 2, border = (long) Math.sqrt(n); v <= border; v += add, add ^= 6)
        while (n % v == 0)
            border = (long) Math.sqrt(n /= last = v);
    return n == 1 ? last : n;
}
        for (i=2; i < number; i++)
        {
            if(isPrime(i))
            {
                 if( number % i == 0)
                 {
                     factorArray.add(i);                    
                 }
            }   
        }