java 大数据 一道java面试题,20亿数字的文本排序,如何取前100?

一道java面试题,20亿数字的文本排序,如何取前100?因为这是一个Java问题,所以这是典型的TOPK问题。首先取前100个数字构建一个最小堆,然后依次从堆的顶部插入剩余的数字,同时调整堆。堆中最

一道java面试题,20亿数字的文本排序,如何取前100?

因为这是一个Java问题,所以这是典型的TOPK问题。首先取前100个数字构建一个最小堆,然后依次从堆的顶部插入剩余的数字,同时调整堆。堆中最后100个元素就是结果。空间复杂度是k,时间复杂度是nlogk

我已经花了60万。我已经工作了10年,但我还是不打印乘法表。在jdk8中,BigInteger的乘法根据两个乘法器的大小采用三种算法。

1. 当两个乘法器的(32x80)幂小于2时,使用双环直接乘法;

2。否则,当两个乘法器都小于2的(32x240)次方时,将使用Karatsuba算法;

3。另外,采用toom-cook乘法算法。

java能写乘法表什么水平?

大数乘法基本上就是乘法垂直计算的编码。

有三个基本功能

1。大数的数组表示。

2. 将大的数字乘以小数得到大的数字。

3. 大数字,大数字,大数字。

对于1,意味着int数组的每个元素都存储若干位。例如,每个元素包含四个十进制数字。[0]商店数万,[1]商店数万、数十万、百万、千万,依此类推。一个数组包含一个很大的数。因此需要一个额外的int变量来记录当前数组中使用了多少元素(类似于字符串长度)。

对于2,“decimal”是指可以用int保存的数字。请注意,只有四个二进制位(与1中提到的数字一致)。

例如,对于数字123456789,[0]保存6789,[1]保存2345,[2]保存1。长度3。

这个大数乘以一个十进制数,如9999,其过程是[0]*9999,即6789*9999=67883211。乘积的下四位( 000)3211保存到乘积的[0](大数),6788的进位保留到[1]。

那么2345*9999=?23447655,加上刚才结转的6788,得到2345443,其中4443保存在产品的[1]中(大数),2345结转到[2]。

等等。

对于3,基本上只是一个For,添加位,然后注意进位。

将一个大数乘以一个大数意味着将第一个大数乘以第二个大数的[0](大数乘以小数点后,上面的2)得到一个大数A0;然后将第一个大数乘以第二个大数的[1],得到一个大数A1,最后是A0,A1相加(即大数相加,3以上)。添加时,请注意A1的[0]应与A0的[1]对齐,A2的[0]应与A1的[1]和A0的[2]对齐这与我们的垂直计算相同。

PS:以上算法基本上是“万位小数”的计算方法。如果数组的每个元素只包含一个十进制位,那么它就是一个十进制数。我们使用10000系统的原因是程序员感觉更好。最有效的用法是将每个int保存到2的15次方,即32768。需要注意的是,如果采用十进制进行计算,程序的计算时间将是10000系统的16倍,即效率为1/16。

PS2:使用int数组时,位数最多只能为4。因为5位数相乘可能得到11位数,这超出了int的范围。