海量数据处理问题。。。
2016-09-16 19:45
267 查看
蓄水池抽样算法
在不知道文件总行数的情况下,如何从文件中随机的抽取一行?给你一个长度为N的链表。N很大,但你不知道N有多大。你的任务是从这N个元素中随机取出k个元素。你只能遍历这个链表一次。你的算法必须保证取出的元素恰好有k个,且它们是完全随机的(出现概率均等)?
top k问题
YoferZhanghttp://blog.csdn.net/zyq522376829/article/details/47686867
july 教你如何迅速秒杀99%的海量数据处理面试题
http://www.cnblogs.com/v-July-v/archive/2012/03/22/2413055.html
leetcode
347. Top K Frequent Elements
题目地址https://leetcode.com/problems/top-k-frequent-elements/
普通的map,加上堆结构(priority_queue)
ac代码:
struct cmp { bool operator()(pair<int, int> p1, pair<int, int> p2){ return p1.second < p2.second; } }; class Solution { public: vector<int> topKFrequent(vector<int>& nums, int k) { vector<int> ans; unordered_map<int, int> mp; int len = nums.size(); for (int i = 0; i < len; i++) { mp[nums[i]] = mp[nums[i]] + 1; } priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> pq; unordered_map<int, int>::iterator it = mp.begin(); while (it != mp.end()){ pq.push(pair<int, int>{it->first, it->second}); ++ it; } while (k-- && !pq.empty()){ pair<int, int> tmp = pq.top(); pq.pop(); ans.push_back(tmp.first); } return ans; } };
基于海量数据的查找 ,统计, 运算等操作。所谓海量数据,就是数据量太大,所以导致要么无法再较短时间内迅速解决,要么是数据太大,导致无法一次性装入内存。从而导致传统的操作无法实现。
分治 + Hash映射
对大文件处理是,若文件过大,无法一次性读入内存,可以考虑采取Hash映射的方法将文件中的元素映射到不同的小文件,然后处理小文件的结构,最后合并处理结果,这样就降低了问题的规模。例题 1: 给定a,b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4GB,请你找出a,b文件共同的url.
5GB * 64 = 320 GB,远大于内存限制的4GB,不能一次性的加载到内存中对文件a,对每个url求取 hash(url) % 1024,分配到1024个小文件中,在这样每个文件约300MB
对文件b,采取同样的做法。这样之后,所有可能相同的url都在对应的小文件(a0 b0)(a1 b1) … 等中,不对应的小文件不可能有相同的url, 这样只要求出1024个对应小文件相同的url.
求每对小文件中相同的url时,可以把其中的一个小文件的url存储到hash_set中。然后遍历另一个小文件的每个url,看其是否在刚才构建的hash_set中,如果是,那么就是共同的url
例题 2: 有10个文件,每个文件1GB,每个文件的每一行存放的都是用户的query,每个文件的query都可能重复。要求你按照query的频度排序。
1
顺序读取10个文件,按照hash(query)%10的结果将query写入到另外10个文件中,记为a0,a1,…,a9,这样新生成的文件每个大小约为1GB;找一台内存在2GB左右的机器,依次对a0,a1,…,a9用hash_map(query,query_count)来统计每个query出现的次数,并利用快速、堆、归并排序按照出现次数进行排序。将排序好的query和对应的query_count输出到文件中。这样得到了10个排好序的文件,记为b0,b1,…,b9这10个文件进行归并排序(可利用败者树进行多路归并)。
2
一般query的总量是有限的,只是重复的次数比较多,若所有的query一次性就可以加入到内存中,就可以采用Trie树 / hash_map等直接统计每个query出现的次数, 然后按出现次数做快速、堆、归并排序就可以了。top K
堆也是海量数据处理经常采用的工具例题1 : 有一个1GB大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1MB。返回频数最高的100个词、
分治法。顺序读文件,对于每个词x,取hash(x) % 5000,然后按照该值存到5000个小文件中,记为x0, x1, … , x4999。这样每个文件为200KB左右。如果其中的有的文件超过1MB,还可以按照类似的方法继续往下分,直到分解得到的小文件的大小都不超过1MB.对每个小文件,统计每个文件中出现的词以及相应的频率(可以采用Trie数或hash_map等),并分别取出出现频率最大的100个词(可以用含100个节点的最小堆),并把这100个词以及相应的频率存入文件,这样又得到了5000个有序(逆序)文件(每个文件有100个词)。下一步就是把这5000个文件进行归并排序(可利用败者树采用多路归并)的过程了。例题2 : 海量日志数据,提取出某日访问百度次数最多的那个IP,假设当前机器可用内存较小,无法一次性读入日志文件。
使用分治思想。因为内存中不能存放所有的数据,为了保证将海量数据分成几个小块后,每个小块中的元素都互不相同,也就是值相同的元素要分到同一个数据块中,可以使用hash的方法,hash(value)%n, n就是要分的块数,这样再每个小块中在使用hash_map的方法统计每个value的频度,在利用堆排序对每个小块的频度进行排序。具体处理过程如下:
IP地址最多有2^32=4GB种取值可能,按照IP地址的hash(IP)%1024值,将海量日志存储到1024个小文件中。每个小文件最多包含4MB个IP地址。
对于每个小文件,可以构建一个IP作为key,出现次数作为value的hash_map,并记录当前出现次数最多的1个IP地址。
有了1024个小文件中的出现次数最多的IP,我们就可以轻松得到总体上出现的最多的IP。
bit-map
bit-map的原理就是使用位数组表示某些元素是否存在,由于采用了bit为单位来存储数据,因此在存储空间方面,可以大大节省,故适用于海量数据的快速查找,判重,删除等。在程序设计中,经常需要判断集合中是否存在重复的问题,当数据量比较大是,位图法比较合适。
例题:已知某个文件内包含一些电话号码,每个号码为8为数字,统计不同号码的个数。
8位数字表示的最大数为999999999(0-99999999的数字),用bit-map解决,则每个数字对应一个bit位,所以只需要约12MB,这样,就用了只有12M左右的内存表示了所有的8位数的电话,一次读入每个电话号码,然后bitmap相应位置为1,最后统计bit-map中1的位数,即为不同的号码个数位图法还可以用来快速判断集合中某个数据是否存在
例题 : 给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在40亿个不重复的数中
unsigned int 最多有232个数,bitmap 申请 232(512 * 2^20*8) 512M的内存例题 : 2.5亿个整数中,找出只出现一次的整数,内存不能容纳这2.5一个数
1 bitmap
每个数2bit 00 表示不存在,01表示只出现一次,10表示出现多次分治 + hash映射
分成小文件,利用hash_map找不重复的整数布隆过滤器
布隆过滤器是一种多哈希函数映射的快速查找算法。它可以判断出某个元素肯定不在集合里或者可能在集合里,即它不会漏报,但可能会误报。通常应用在一些需要快速判断某个元素是否属于集合,但不严格要求100%正确的场合。参考
http://www.cnblogs.com/Jack47/p/bloom_filter_intro.html
倒排索引
相关文章推荐
- 15道海量数据处理的问题,牛人不牛人都可以试试!
- 海量数据处理问题与方法汇总
- 海量数据处理问题学习笔记
- 海量数据处理问题 分而治之 hash表 堆排序
- 海量数据处理之排序问题
- 海量数据的处理问题
- 面试笔试问题:大数据量,海量数据 处理方法总结
- 海量数据处理之排序问题
- 海量数据处理的 Top K算法(问题) 小顶堆实现
- 海量数据处理问题
- 15道海量数据处理的问题,牛人不牛人都可以试试!
- 海量数据问题处理
- 面试中的海量数据处理问题
- 海量数据处理之排序问题
- 海量数据处理问题汇总及方法总结
- 计算机专业面试笔试问题之大数据量,海量数据 处理方法总结
- 海量数据的处理问题
- [MapReduce编程]用MapReduce大刀砍掉海量数据离线处理问题。
- 关于海量数据处理问题
- 海量数据处理问题