一: A、B两个整数集合,设计一个算法求他们的交集,尽可能的高效。
解法一参考:http://blog.csdn.net/thebestdavid/article/details/12056293
第一种方法:对A、B 两个集合分别进行排序,之后再对排完序的集合继续比较操作,相同的即为交集
第二种方法:利用C++的map,先插入A集合,再一一对B集合继续插入若失败则为交集,这种做法在不考虑
集合大小的情况下确实是一种比较简单的方法。(若不直接用数据结构,类似于hash映射)
第三种方法:转自:http://www.cnblogs.com/i2u9/p/intersection.html
思想: 位图标示数字
1 遍历 集合A,求出 最值,效率 1.5n ,计算最大值与最小值的差为LA。对B一样求出最值的差为LB。
2 新建一块空间 M,大小为 min( LA, LB ) / 8 取整 +1 个字节
3 遍历 最值差 小的 集合
设置M的第j个比特为1(从0开始),j 为 每个 元素 与 该集合 最小值的差。
设置 第j个比特为1 的方法:使用 unsigned char 指针p 指向 M,*(p+j/8) |= 1 << j%8
4 遍历 另外一个 集合
以 每个元素 与 前一个 集合 最小值的 差 为 k,若 k 小于 0 或 大于 min(LA,LB) 则 该 元素 不属于 交集
再 查看 M 中 第 k 个 比特 是否 为 1,若是 则 该元素 属于 交集 ,否则 不是。
转自:http://blog.csdn.net/mingming_bupt/article/details/6340485
二:给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
方案1:可以估计每个文件安的大小为5G×64=320G,远远大于内存限制的4G。所以不可能将其完全加载到内存中处理。考虑采取分而治之的方法。遍历文件a,对每个url取余 ,然后根据所取得的值将url分别存储到1000个小文件中(集合A)。这样每个小文件的大约为300M。遍历文件b,采取和a相同的方式将url分别存储到1000各小文件(集合B)。这样处理后,所有可能相同的url都在对应的小文件(A、B )中,不对应的小文件不可能有相同的url。然后我们只要求出1000对小文件中相同的url即可。求每对小文件中相同的url时,可以把其中一个小文件的url存储到hash_set中。然后遍历另一个小文件的每个url,看其是否在刚才构建的hash_set中,如果是,那么就是共同的url,存到文件里面就可以了。
方 案2:如果允许有一定的错误率,可以使用Bloom filter,4G内存大概可以表示340亿bit。将其中一个文件中的url使用Bloom filter映射为这340亿bit,然后挨个读取另外一个文件的url,检查是否与Bloom filter,如果是,那么该url应该是共同的url(注意会有一定的错误率)。