如何存储10亿的数据

最近突然想到这么一个问题:

假如有<10亿的数据,每个数据不重复,同时是无序,不连续的,如何使用最小的空间来存储来这么多数据,同时又能快速的确认哪个数据有没有。

  • 直接存储10亿个数据

一个int的类型,可以最大可以表示:2147483647,这个数大于10亿,所以可以使用一个int(4个字节)来表示一个数。

在这种情况下,需要的空间是4*10^9,大约需要4G的空间。

如果想去查找一个数据在或不在,此时需要把这么多的数据加载到内存中,分别遍历,需要O(n)的时间复杂度。

  • 利用数组的index来存储

数组有一个优势就是可以根据index直接找到数据,正常情况下都是利用数组的空间来存储数据,现在是不是可以反过来利用index来表示数据。

数组的index默认从0增长到n,这个问题中说明了每个数据不重复,这个很符合index的特征,index是不可能重复的。

虽然说这组数据是无序和不连续的,可以将数组初始化成全零,对应存在的index将数据置1,

C/C++中可以构成数组最小的类型是char,那就可以new char[1024*1024*1024]的数组,如果对应index的数据纯在a[n]=1.

在这种情况下,需要的空间是10^9,大约是1G的空间

这个时候如果想查看一个数据在不在,只需要O(1)的时间复杂度。

  • 基于数组的index的位存储

上面的方案已经将空间压缩1/4,是不是还有更优的方案呢?

其实只需要表示一个数字在或不在,那只要0和1就够。

这个时候数组的大小只需要10^9/8就够了,大约130MB,这么大直接加载到内存中也没有问题。

在这种情况下如何访问呢

假设想查看1000这个数在不在,可以通过以下方式:

index = 1000 / 8 = 125

pos = 1000 % 8 = 0

也就是说a[125]的0位表示的是1000。

通过a[index]&(0x01<<pos)来判断数据是不是存在

通过a[index] |= (0x01<<pos)来进行赋值

通过对比发现,通过位运算能够最大程度的减小存储空间,通过也能做到快速访问。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值