java-计算BigInteger的乘积[]
作者:互联网
上下文:我正在尝试使用Java中的BigInteger类(对于n> 100,000)来计算非常大的n的阶乘,到目前为止,我正在做什么:
>使用Erasthones筛产生所有小于或等于n的素数
>查找将提高到哪些能力.
>将所有数字加到各自的幂.
>使用分治法递归方法将它们全部相乘.
根据我在互联网上所做的研究,这比简单地将所有k乘以n渐近地快.但是,我注意到,实现过程中最慢的部分是我将所有素数乘以的部分.我的问题是:
>是否有更快的方法来计算大量数字的乘积?
>我的实施可以改善吗?
码:
public static BigInteger product(BigInteger[] numbers) {
if (numbers.length == 0)
throw new ArithmeticException("There is nothing to multiply!");
if (numbers.length == 1)
return numbers[0];
if (numbers.length == 2)
return numbers[0].multiply(numbers[1]);
BigInteger[] part1 = new BigInteger[numbers.length / 2];
BigInteger[] part2 = new BigInteger[numbers.length - numbers.length / 2];
System.arraycopy(numbers, 0, part1, 0, numbers.length / 2);
System.arraycopy(numbers, numbers.length / 2, part2, 0, numbers.length - numbers.length / 2);
return product(part1).multiply(product(part2));
}
>请注意,BigInteger使用karatsuba算法进行乘法.
>我知道关于计算阶乘有很多问题.但是我的工作是计算没有太多资源的BigIntegers乘积. (我见过有人说“使用分而治之方法”,但我不记得在哪里,也没有见到任何实现.
解决方法:
一种提高性能的方法是执行以下操作:
>对您需要相乘的数字数组进行排序
>创建两个新列表:a和b.
>对于输入列表中您需要相乘的每个数字,它可能会出现多次.假设数字v_i出现了n_i次.然后将v_i加到a n_i / 2次(向下舍入).如果n_i为奇数,请将v_i也添加一次.
>要计算结果,请执行以下操作:
BigInteger A = product(a);
BigInteger B = prudoct(b);
return a.multiply(a).multiply(b);
要查看其工作原理,请考虑您的输入数组为[2,2,2,2,2,3,3,3].因此,有四个2和三个3.数组a和b将分别为
a = [2, 2, 3]
b = [3]
然后,您将递归调用以计算这些乘积.请注意,我们将要乘数的数量从7减少到4,几乎减少了两倍.这里的窍门是,对于多次出现的数字,我们只能计算其中一半的乘积,然后将其乘以2的幂.非常类似于如何在O(log n)时间中计算数字的幂.
标签:multiplication,biginteger,java,algorithm 来源: https://codeday.me/bug/20191120/2040364.html