转载:http://hxraid.iteye.com/blog/649831
题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。只写出思路即可(内存限制为
2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存)。
分析:
既然要找中位数,很简单就是排序的想法。那么基于字节的桶排序是一个可行的方法
(请见《桶排序
》):
思想:将整形的每1byte作为一个关键字,也就是说一个整形可以拆成4个keys,而且最高位的keys越大,整数越大。如果高位keys相同,则比较次高位的keys。整个比较过程类似于字符串的字典序。
第一步:把10G整数每2G读入一次内存,然后一次遍历这536,870,912个数据。每个数据用位运算">>"取出最高8位
(31-24)。这8bits(0-255)最多表示255个桶,那么可以根据8bit的值来确定丢入第几个桶。最后把每个桶写入一个磁盘文件中,同时在
内存中统计每个桶内数据的数量,自然这个数量只需要255个整形空间即可。
代
价:(1)
10G数据依次读入内存的IO代价(这个是无法避免的,CPU不能直接在磁盘上运算)。(2)在内存中遍历536,870,912个数据,这是一个
O(n)的线性时间复杂度。(3)把255个桶写会到255个磁盘文件空间中,这个代价是额外的,也就是多付出一倍的10G数据转移的时间。
第二步:根据内存中255个桶内的数量,计算中位数在第几个桶中。很显然,2,684,354,560个数中位数是第1,342,177,280个。假设
前127个桶的数据量相加,发现少于1,342,177,280,把第128个桶数据量加上,大于1,342,177,280。说明,中位数必在磁盘的第
128个桶中。而且在这个桶的第1,342,177,280-N(0-127)个数位上。N(0-127)表示前127个桶的数据量之和。然后把第128
个文件中的整数读入内存。(平均而言,每个文件的大小估计在10G/128=80M左右,当然也不一定,但是超过2G的可能性很小)。
代价:(1)循环计算255个桶中的数据量累加,需要O(M)的代价,其中m<255。(2)读入一个大概80M左右文件大小的IO代价。
注意,变态的情况下,这个需要读入的第128号文件仍然大于2G,那么整个读入仍然可以按照第一步分批来进行读取。
第三步:继续以内存中的整数的次高8bit进行桶排序(23-16)。过程和第一步相同,也是255个桶。
第四步:一直下去,直到最低字节(7-0bit)的桶排序结束。我相信这个时候完全可以在内存中使用一次快排就可以了。
整个过程的时间复杂度在O(n)的线性级别上(没有任何循环嵌套)。但主要时间消耗在第一步的第二次内存-磁盘数据交换上,即10G数据分255个文件写回磁盘上。一般而言,如果第二步过后,内存可以容纳下存在中位数的某一个文件的话,直接快排就可以了。
分享到:
相关推荐
这可能涉及到将一个整数转换成另一种形式,比如寻找最小的数字表示、位操作或者数学上的等价表达。例如,一个问题可能是要求找到一个整数的最小二进制表示,同时满足某些条件,如不包含连续的1或0。在这种情况下,...
接着,根据中位数将数组分为两部分,重复此过程,比较新中位数的数量。当子数组无法再分时,记录的结果即为原问题的解。 2. **设计思路**:首先对n个数排序,记录中位数x及其出现次数y。接着,将数组按中位数位置...
在有内存限制的情况下找出10G个整数中的中位数问题,可以考虑使用“中位数的中位数”算法,该算法可以将复杂度降低到O(N)。 时分秒针在一天之内重合的次数,可以通过分析它们的运动规律计算得出。 将多个集合合并...
2. 给定10个文件,每个文件1G,每个文件的每一行存放的是用户的query,每个文件的query都可能重复。需要按照query的频度排序。解决方法是使用Trie树来统计每个query的频度,然后使用堆排序来输出频度最高的query。 ...
子程序 到十进制, 整数型, 公开, 将2,8,16进制文件转换到10进制数值(返回十进制数) .参数 文本, 文本型, , 2,8,16进制文件 .参数 进制, 整数型, 可空, 默认为十六进制 2为二进制,8为八进制,16为16进制 .子程序 读...
具体来说,输入两个整数 a 和 b,需要将 a 的个位与十位交换,并将结果与 b 的个位、十位、百位组合起来形成一个新的整数 c。 **实现方法:** - 提取 a 的个位和十位数字。 - 将提取的数字交换位置。 - 提取 b 的个...
8. **C循环-求各位数字之积.c**:需要通过循环取出整数的每一位,然后逐位相乘,得到所有位数的乘积。 9. **求sn=a+aa+aaa+aaaa+......的值.c**:这个任务可能涉及到字符串处理和动态生成字符串,需要理解字符串...
6. **整数转字符串并填充前导零**:如果你需要将整数转换为带有前导零的字符串,可以使用`CString`的`Format()`函数,例如`str.Format("%03d", n)`,这将确保结果始终为三位数,不足三位则前面填充零。 7. **源文件...
8. **EULER 函数 Ψ**:EULER 函数 Ψ 计算小于等于给定数 n 的所有正整数的约数个数的乘积,Ψ(74)的值为343。 9. **分配排序**:分配排序是一种将数据分布到多个桶中,然后逐个收集排序的排序方法。例如,基数...
当调用 `malloc(1.2G)` 时,如果物理内存不足,操作系统会将部分数据移到磁盘上的交换文件(swap file)中,从而腾出物理内存空间供新分配的内存使用。因此,在大多数情况下,即使物理内存不足1.2GB,系统也能通过...
编程对给定的N和S,寻找一种方案使得剩下的数字组成的新数最小(输出应包括所去掉的数字的位置和组成的新的正整数,N不超过240位)。 21、 对于下图给出的有向网,写出用Dijkstra方法求从顶点A到图中其它顶点的最短...
- 大写字母G的ASCII码为41 + 7 = 48(16进制),转换为10进制是72。 - 小写字母b的ASCII码为41 + 32 + 1 = 74(16进制),转换为10进制是116。 - 小写字母t的ASCII码为41 + 32 + 2 = 75(16进制),转换为10进制...
在这个题目中,我们面对的是一个基于生物信息学的算法问题,具体来说是寻找两个DNA序列的最大公共子序列(Longest Common Subsequence, LCS)的长度。这是一个经典的计算机科学问题,通常用于比较序列间的相似性,...
4、改善(字节集_取左边|取右边|取中间)与未公开子程序重复,改名为 字节集_寻找取左|字节集_寻找取右|字节集_寻找取中,并修正BUG。 5、公开子程序(字节集_到文本|字节集_到整数|字节集_取左边|字节集_取右边|...
根据给定文件的信息,我们可以总结出以下几个与 ACM 数论相关的知识点: ### 1. 最大公约数(GCD)与最小公倍数(LCM) #### 核心知识点: - **定义**:最大公约数(Greatest Common Divisor, GCD)是指两个或多个...
第一位目击者说车牌的前两位数字相同,第二位目击者说车牌的后两位数字相同,第三位目击者(数学家)说车牌号码是一个四位整数的平方。请求出该车牌号。 **代码解析**: ```c #include #include int main() { int...
在上述代码中,`cv::Sobel()`函数完成了Sobel算子的操作,`CV_8U`表示结果图像的数据类型为8位无符号整数,1和1是水平和垂直方向的差分数,3是应用的卷积核大小。 ### 文件说明 在提供的压缩包文件中,有以下几个...