今天面试的一道算法题,求解
有10G 的日志文件 存储格式为 [cmd:from:abc@163.com,to:123@qq.com]
设计一个算法,求出由163域发出的邮件,接受最多的前50个域
如 abc@163.com 发到 123@qq.com 如果QQ邮箱接受是前50多的,则显示出来,并且显示有多少条是从163到QQ的
我想到的是用multimap容器来存储信息~~
求解答
[解决办法]
这样啊行?
10G文件先分成若干小于机器内存的文件,然后逐个读取一遍 判断那些由163发出的邮件 记下目的域
可以使用hash表存储 条数信息
[解决办法]
接着 gogdizzy(天下第一好大人) 说:
也可以不对哈希表里所有的value排序,维护一个含有50个元素的最小堆,堆的元素就是value。每个value值同堆的第一个元素比较,若小于堆的第一个元素,继续下一个,若大于,替换堆的第一个元素。最后堆的50个元素就是前50多。如果要求有序,再对前50多排序
[解决办法]
不知道我理解对不对,题目是求前50个出现最多的收件人邮件域,即类似@XXX.com
那么我们可以假设,日志文件中的所有邮件域不是一个很大的数据,也许不超过一两万;
这样,你只要建立一个以邮件域为key,接收邮件次数为Value的dictionary
然后打开日志,一行一行地读这个文件,如果发件人是@163.com就处理,否则下一行;
将符合上述条件的收件人邮件域累计到dictionary中即可。
示例:
Dictionary<string, long> DictOfDomain=new Dictionary<string, long>();
//do(file!=eof)
string key = "@qq.com";//经过确认是163发出的收件人邮件域
if (DictOfDomain.ContainsKey("key")) { DictOfDomain[key] += 1; } else { DictOfDomain.Add(key, 1); }
//end do
最后对dictionary的value进行排序,就可以得到前50邮件域