大数的素数因子分解

Way*_*ney 3 java algorithm prime-factoring

我想找到小于10 ^ 12的大数的素数因子分解.我得到了这段代码(在java中):

public static List<Long> primeFactors(long numbers) {
        long n = numbers;
        List<Long> factors = new ArrayList<Long>();
        for (long i = 2; i <= n / i; i++) {
            while (n % i == 0) {
                factors.add(i);
                n /= i;
            }
        }
        if (n > 1) {
            factors.add(n);
        }
        return factors;
    }
Run Code Online (Sandbox Code Playgroud)

首先,上述算法的复杂性是什么?我很难找到它?

对于素数较大的数字来说,它也会太慢.

是否有更好的算法,或者如何优化这个算法?

tob*_*s_k 16

如果你想要分解许多大数,那么你可能最好先找到素数sqrt(n)(例如使用Eratosthenes的Sieve).然后你必须只检查那些素数是否是因子而不是全部测试i <= sqrt(n).


Pet*_*hev 5

复杂性是O(sqrt(n)).检查后的数字是没有意义的sqrt(n).

这意味着,对于10^12,它将在大多数1 000 000迭代中进行,这并不慢.

  • 预先计算高达10 ^ 6的素数将使其快10倍 (2认同)

Pet*_*rey 5

对大数进行因子分解是一个难题,这也是加密算法使用大素数因子使加密难以破解的部分原因.

public static void main(String... args)  {
    int nums = 100;
    for (int i = 0; i < nums; i++) {
        long start = System.nanoTime();
        primeFactors(Long.MAX_VALUE - i);
        long time = System.nanoTime() - start;
        if (time > 100e6)
            System.out.println((Long.MAX_VALUE-i) + " took "+time/1000000+" ms.");
    }
}

public static List<Long> primeFactors(long n) {
    List<Long> factors = new ArrayList<Long>();
    while (n % 2 == 0 && n > 0) {
        factors.add(2L);
        n /= 2;
    }

    for (long i = 3; i * i <= n; i+=2) {
        while (n % i == 0) {
            factors.add(i);
            n /= i;
        }
    }
    if (n > 1)
        factors.add(n);

    return factors;
}
Run Code Online (Sandbox Code Playgroud)

版画

9223372036854775806 took 3902 ms.
9223372036854775805 took 287 ms.
9223372036854775804 took 8356 ms.
9223372036854775797 took 9519 ms.
9223372036854775796 took 1507 ms.
9223372036854775794 took 111 ms.
9223372036854775788 took 184 ms.
Run Code Online (Sandbox Code Playgroud)

如果将Long.MAX_VALUE替换为1000000000000L,则它们都会在20 ms内进行分解.