1G内存2G文件找出现最多次QQ号算法

来源:互联网 发布:c语言考研知识点总结 编辑:程序博客网 时间:2024/05/03 17:28

题目:服务器内存1G,有一个2G的文件,里面每行存着一个QQ号(5-10位数),怎么最快找出出现过最多次的QQ号

看来网上不少交流,发现大家都觉得1G内存放不下上面的数据

其实是可以放得下的,只要700M左右就可以在内存里放下这些数据,不需要外排

 

完全不需要写硬盘,位图+分区思想可以在内存把334M行10位数QQ号完成统计 

详解: 9999999999 = 0x2540BE3FF 把QQ号分成0x2530B=152587个段,每个段对应一个内存文件(自己用算法实现对这些文件的动态扩展写操作)

这样每个文件里,一个QQ号就只剩下2字节,

2G/6=333M=3.33亿个QQ号 ×2字节=666MB,需要写入内存虚拟文件

只要遍历硬盘文件,然后写入内存虚拟文件 666MB可以放得下,算上文件描述的消耗不超过700MB

然后对每个虚拟内存文件做bitmap统计出最多的,66536×4=256KB解决 所以内存只需要不到700MB就能解决这个问题

伪代码:----------------------

初始化152587个内存文件

循环直到2G文读完

{

用批量读QQ号的函数(自己写)读QQ号到int64数组(比如一次1万个)

取得文件号=QQ号/0x10000,QQ尾数=QQ号&0xFFFF,将2字节的QQ尾数写入对应内存文件

}

//到这里,内存估计消耗了700M

int64 QQ号 = 0;

int 出现次数 = 0;

循环每个内存文件

{

int bitmap[0x10000] = {0}; bitmap统计数组初始化

清空bitmap

 

循环,每次性读1KB的QQ尾数数组,直到完

{

根据尾数,在bitmap对应统计数+1

}

循环0x10000次bitmap每个统计数,找到最大的次数的尾数,和QQ号/出现次数变量做max操作

}

输出QQ号和次数

清空内存文件

------------------------

 

时间=

遍历硬盘文件(2GB/100MB/s约20s)+

数字文本转换成二进制数值(3s内解决,scanf速度可能不够快,自己写数字转化算法)+

写内存虚拟文件333M次(以现在内存速度5s内解决)+

152587次对每个内存虚拟文件bitmap(总计333M次计数+10G次max,15s内解决,CPU周期3GHz应当是可以做到的)

估算小于20+3+5+15=43s

而且这个算法可以CPU并行化,而有关外排的并行化那是惨不忍睹的

原创粉丝点击