Java 如何有效地从数十亿个数字中找出10个最大的数字?
问题陈述:从包含数十亿个数字的文件中最多查找10个数字 输入:Java 如何有效地从数十亿个数字中找出10个最大的数字?,java,arrays,algorithm,Java,Arrays,Algorithm,问题陈述:从包含数十亿个数字的文件中最多查找10个数字 输入: 97911 98855 12345 78982 ..... …. 我实际上想出了下面的解决方案 最佳案例复杂性O(n)-当文件中的数字按降序排列时 当文件的数字按升序排列时,最坏情况的复杂性O(n*10)~O(n) 平均值 复杂性~O(n) 在所有情况下,空间复杂度都是O(1) 我正在使用文件读取器和存储最多10个数字的排序数组读取文件。我将检查currentLine是否大于数组中的最小元素-如果大于,将通过交换将其插入正确的位
97911
98855
12345
78982
.....
….
我实际上想出了下面的解决方案
- 最佳案例复杂性
-当文件中的数字按降序排列时O(n)
- 当文件的数字按升序排列时,最坏情况的复杂性
O(n*10)~O(n)
- 平均值
复杂性~
O(n)
O(1)
我正在使用文件读取器和存储最多10个数字的排序数组读取文件。我将检查currentLine是否大于数组中的最小元素-如果大于,将通过交换将其插入正确的位置
Scanner sc = new Scanner(new FileReader(new File("demo.txt")));
int[] maxNum = new int[10];
while(sc.hasNext()){
int phoneNumber = Integer.parseInt(sc.nextLine());
if(phoneNumber>maxNum[9]){
maxNum[9] = phoneNumber;
for(int i =9;i>0;i--){
if(maxNum[i]>maxNum[i-1]){
int temp = maxNum[i];
maxNum[i] = maxNum[i-1];
maxNum[i-1] = temp;
}
}
}
}
我正在寻找反馈,如果有更好的方法来实现这一点如果文件未排序,您必须至少查看文件中的每个数字一次,因为它可能是最大的10个数字之一。因此O(n)是你能达到的最好的结果
通过使用最小堆替换
maxNum
数组,可以进行一些优化(但是不改变渐进复杂性)。如果要查找的数字的计数足够大(假设您正在查找最大的100个数字),则运行速度会更快。在10时可能还没有回报。一般来说,从N个数中找出K个最大数:
您可以通过多线程和并行化来改进算法。这意味着运行20个线程,将文件划分为20个文件,并在每个部分找到最大的10个数字。最后,在您维护的20个数组(每个数组的长度为10)中找出最大的10个数 关键是操作是从文件或数据库中读取,而不是写入。因此,应该可以通过不同的线程并行访问文件的不同部分。即使您的输入在内存中,这也比单纯的搜索快。这仍然是O(n),但取决于它们并行运行的线程数(比如t),它使用大约n/t比较。这意味着它比一个简单的算法快约t倍
最后我要说的是,小数组上的位优化作为主要时间是无用的,重点是如何维护一个大文件而不是维护一个小数组。FYR,
O(n*10)
与O(n)
相同。您可以使用内置方法来查找最大值,每当找到最大值时,请存储该值,然后将其删除,然后再执行10次。@Null。你建议采用哪种内置方法。。它是否不需要多次传递和更多的迭代检查,它将帮助您。值是否有上限?是的,如果所需的最大数更多,这是真的。。但是对于10个数字,正如您所说的,数组会快得多。我看不出有任何理由不在这里使用min heap
,这种实现在交换操作方面有更多的成本,不需要将它们按顺序排列,只需在从堆顶部轮询时执行一次即可。@Xlee。当然将运行一些基线测试并查看差异。答案只是说OP正在做的是好的,而不是。在最好的情况下,它可以是一个评论。事实上,这个答案应该删除。@SaeedAmiri显然,我有不同的观点。对于单线程解决方案,OP接近最佳值。正如你所建议的,使用并行处理可以归结为“购买一台功能更强大的机器”,正是因为这个原因,它的速度更快。答案是缺少处理大文件的主要内容,而是提供了一些类似维基百科的信息。这些只是一般信息。@SaeedAmiri:在这三点中,我都清楚地提到了如何将算法应用于磁盘上的大数据。我的意思是,主要的一点是并行执行,而不仅仅是noraml顺序执行。@SaeedAmiri:在OP的帖子中,他在哪里说他有多台计算机用于并行?并行性不应该是首要考虑的问题。创建数据无法放入内存的算法更为重要。OP不需要说,你应该醒悟,现在不是1970年,即使手机有多处理器。你只是重复了1970年的教科书。阅读我对另一个答案的评论。