在最近的一次采访中被问及
有一个包含一百万个整数的日志文件。每个整数的长度为32位。可能会重复日志文件中的特定整数值。您可以按顺序读取日志文件。您还可以按顺序读取和写入临时文件;对于可以随时打开的文件数量没有限制。但是,在任何给定时间内,您可以在内存中保留不超过2000个整数。
我被要求生成一个直方图,显示日志文件中出现的每个整数值的绝对计数,并说明每个整数必须加载到内存中的顺序复杂性的上限
答案 0 :(得分:4)
这是一个令人困惑的问题。难道你不能只读取2000个数字,对它们进行排序,然后写入临时文件吗?做500次,然后进行N路合并。每个号码都会被加载到内存中两次。
如果你必须在只有2 GB内存的计算机上对一个TB级文件进行排序,那就是你要做的事情。
答案 1 :(得分:3)
打开2个 32 临时文件,每个整数一个。按顺序读取日志文件一次。每当读取整数 n 时,将“1”写入临时文件编号 n 。然后通过遍历所有临时文件生成直方图。每个整数只被读入内存一次,因此它是O(n)算法。
答案 2 :(得分:0)
读/写文件没有限制 =每个数字计数将存储在一个文件中。
32位长度的数字=每个 file是一个数字和文件名 是代表的32位 整数(可以使用整数值 ()
显示直方图(表示没有订单 需要)
伪代码:
count = 2000
HashMap<number, number> = new
code:readbuffer
while count != 0
read NextNumber
if HashMap.HasKey NextNumber then HashMap[NextNumber]++
else HashMap[NextNumber]=1
count --;
end while
code:flushbuffer
foreach Key in HashMap
if exists FileName Key.ToBinnary
FileValue += HashMap[HashKey]
else WriteNewFile FileName=Key.toBinnay; SetValue = 1
end foreach
code: histogram
each file name is the number;
each file value is the count.
费用:readbuffer
读取的序号= 2M(M =百万)
Map.HasKey =(在2000条记录中搜索密钥,最坏情况下数字不存在,摘要(Σ2000)x2M)
Map上的SetValue与上面的费用相同
总计:(2M)+(2MxΣ2000)x2
费用:flushbuffer File.exists 2M
费用:直方图 2M
总计= 6M +4MxΣ2000
答案 3 :(得分:0)
实施基于文件的B树。
文件名是GUID。
文件内容是: 数见过 计数 左侧节点文件 右节点文件
一次通过后,复杂性可以从B树的复杂性中获得。
你的历史记录隐含在结构中。