新增开放性问题方案

pull/4/head
liruyu 3 years ago
parent b41da914e2
commit 1e054c637d

@ -0,0 +1,83 @@
<div style="color:#16b0ff;font-size:50px;font-weight: 900;text-shadow: 5px 5px 10px var(--theme-color);font-family: 'Comic Sans MS';">Open</div>
<span style="color:#16b0ff;font-size:20px;font-weight: 900;font-family: 'Comic Sans MS';">Introduction</span>:收纳开放性设计问题相关的知识总结!
[TOC]
# 开放性设计
## 求两个文件中的QQ交集
**问题**A文件有30亿个QQ号码B文件有40亿个QQ号码求A文件和B文件中QQ号码的交集内存大小限制为1GB。
### 方案一:直接暴力比较
最简单的方法是直接暴力比较双重循环比较。显然这种方法要比较的次数是30亿×40亿时间复杂度太大。
### 方案二利用hashmap
将B文件中的40亿个QQ号码放入Hash表中然后遍历B文件中的30亿个QQ号码准一判断是否已在Hash表中存在。
显然应该用哈希表优化查找速度使得时间复杂度大大降低只需要遍历上面一层即可。然而空间的占用还是太大了1GB的内存根本无法容纳40亿个QQ号。
### 方案三:分治切割文件
既然内存容纳不下那就想办法进行切割比如根据QQ号码的最后一位的值来切割A文件和B文件使文件变小。显然尾数为j的QQ号码只可能在Aj文件和Bj文件中只需要比较Aj和Bj文件即可。
| QQ号最后一位 | A文件的切割 | B文件的切割 |
| ------------ | ----------- | ----------- |
| 0 | A0 | B0 |
| 1 | A1 | B1 |
| 2 | A2 | B2 |
| 3 | A3 | B3 |
| ... | ... | ... |
通过切割的方法可以化大为小让内存容纳得下。需要强调的是仅仅以QQ号最后一位来划分那么每个小文件的数据量大约是原来文件的1/10, 可能还是偏大。所以可以考虑以QQ号的最后3位来划分那么每个小文件的数据量大约是原来大文件的1/1000甚至还可以更细地来进行划分。通过一定的规则进行分割把A文件和B文件中同类型数据划分到对应的小文件中解决了内存问题。
### 方案四利用bitmap
可以对hashmap进行优化采用bitmap这种数据结构可以顺利地同时解决时间问题和空间问题。
| bit | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
| ----- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| index | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1个unsigned char类型的数据可以标识0~7这8个整数的存在与否。以此类推
- 1个unsigned int类型数据可以标识0~31这322^5个整数的存在与否
- 2个unsigned int类型数据可以标识0~63这642^6个整数的存在与否
- 3个unsigned int类型数据可以标识0~127这1282^7个整数的存在与否
- 4个unsigned int类型数据可以标识0~255这2562^8个整数的存在与否
- ......
- 28个unsigned int类型数据可以标识0~2^32-1这43亿2^32个整数的存在与否
10位QQ号码的理论最大值为 2^32 - 1 ≈ 43 亿bit。
占用内存43亿bit≈5.37亿bytes≈52万KB≈512MB
显然可以推导出512MB大小足够标识所有QQ号码的存在与否请注意QQ号码的理论最大值为2^32 - 1大概是43亿左右。接下来的问题就很简单了
用512MB的unsigned int数组来记录B文件中QQ号码的存在与否形成一个bitmap。然后遍历A文件中的QQ看是否在bitmap中如果在那么该QQ号码就同时存在于A和B两个文件中。
https://mp.weixin.qq.com/s/Q_EvlN9LvkdA5M5EharBBA
## 40亿个QQ号码如何去重
文件中有40亿个QQ号码请设计算法对QQ号码去重相同的QQ号码仅保留一个内存限制1G。
https://mp.weixin.qq.com/s/YlLYDzncB6tqbffrg__13w
### 方法一:排序
### 方法二hashmap
### 方法三:文件切割
### 方法四bitmap
Loading…
Cancel
Save