无重复海量数据求排序
bitmap法。
例题:电话号码排序
有重复海量数据求排序
例题:有重复的电话号码排序
可以把电话号码当成大整数。
自己猜想解决方案:
法一:
法二:
海量数据求重复次数最多的top k记录
注意这种求出现次数top k的问题还是要转化为求先求出每个记录出现的次数后,再求top k大。top k大的话则用小根堆比较方便了。
法一: (假如这些数据能放进内存的情况下)
法二:(假如内存不够放这些数据的Hash统计表)
法三:
是否还有其他方法?
附:top K问题的特殊例子: top 1
例如ip访问日志, 求出现频率最高的ip
算法思想:分而治之+Hash
按照IP地址的Hash(IP)%1024值,把海量IP日志分别存储到1024个小文件中。这样,每个小文件最多包含4MB个IP地址;
对于每一个小文件,可以构建一个IP为key,出现次数为value的Hash map,同时记录当前出现次数最多的那个IP地址;
可以得到1024个小文件中的出现次数最多的IP,再依据常规的排序算法得到总体上出现次数最多的IP;
多个文件海量数据排序
例题:有10个文件,每个文件1G,每个文件的每一行存放的都是用户的query,每个文件的query都可能重复。要求你按照query的频度排序。
法一:
顺序读取10个文件,按照hash(query)%10的结果将query写入到另外10个文件(记为)中。这样新生成的文件每个的大小大约也1G(假设hash函数是随机的)。
找一台内存在2G左右的机器,依次对用hash_map(query,query_count)来统计每个query出现的次数。利用快速/堆/归并排序按照出现次数进行排序。将排序好的query和对应的query_cout输出到文件中。这样得到了10个排好序的文件(记为)。
对这10个文件进行归并排序(内排序与外排序相结合)。
法二:
两个大文件求重复的记录
例题:给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
法一:
遍历文件a,对每个url求取hash(url)%1000,然后根据所取得的值将url分别存储到1000个小文件(记为a0,a1,...,a999)中。这样每个小文件的大约为300M。
遍历文件b,采取和a相同的方式将url分别存储到1000小文件(记为b0,b1,...,b999)。
这样处理后,所有可能相同的url都在对应的小文件(a0vsb0,a1vsb1,...,a999vsb999)中,不对应的小文件不可能有相同的url。然后我们只要求出1000对小文件中相同的url即可。
法二:
海量数据求不重复出现的记录。
例题:在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数。
法一:
采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义)进行,共需内存2^32 * 2 bit=1 GB内存,还可以接受。
然后扫描这2.5亿个整数,查看Bitmap中相对应位,如果是00变01,01变10,10保持不变。所描完事后,查看bitmap,把对应位是01的整数输出即可。
法二:
海量数据中查找
例题:腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
法一:
法二:(编程珠玑里面的方法)
然后将这40亿个数分成两类:
最高位为0
最高位为1
并将这两类分别写入到两个文件中,其中一个文件中数的个数<=20亿,而另一个>=20亿(这相当于折半了);
再然后把这个文件为又分成两类:
次最高位为0
次最高位为1
并将这两类分别写入到两个文件中,其中一个文件中数的个数<=10亿,而另一个>=10亿(这相当于折半了);
.......
以此类推,就可以找到了,而且时间复杂度为O(logn)
参考资料
编程珠玑
http://blog.youkuaiyun.com/v_JULY_v
出处:https://www.cnblogs.com/xawei/p/6726620.html
本文探讨了多种海量数据处理策略,包括使用Bitmap优化内存占用,通过Hash分布减少数据规模,以及运用小根堆、分而治之等算法解决topk、排序和查找问题,适用于电话号码排序、IP访问频率统计等场景。

被折叠的 条评论
为什么被折叠?



