【算法学习】大数据题目和位运算

目录

技巧

在这里插入图片描述

例题

在这里插入图片描述
(1)32位整数的范围是0~( 2 32 2^{32} 232 -1),如果用字节存储,就是 2 32 2^{32} 232/8约等于500M,每个位置只有0或1,表示这个数是不是出现过

(2)进阶:
10MB约等于3kb,定义一个int[]数组,数组每一个元素占4字节,3kb/4字节,相当于每个4字节占用差不多512空间,即需要512个int,现在相当于把2^32分到512空间(512个int),即每个int分到8388608( 2 32 2^{32} 232/512).
int[]是用来做词频统计的,对于每一个数字,除以8388608可以分到int[]中不同位置,即对应位置词频++,40亿个数字分完后,一定有一个区间不够8388608
定位到某个范围后,重复上面的过程,直到定位到对应的数字

(3)变形:能不能使用更少的空间
不断二分
在这里插入图片描述
2. 在这里插入图片描述
哈希表统计词频,词是对应的hash key
多个小文件大根堆,然后把每个小根堆堆顶放到一个总的大根堆中,此时可以弹出甲,然后第二个小文件大根堆再放一个丙到总堆,重复操作
在这里插入图片描述
3. 在这里插入图片描述
法一:1G内存八字节,可以知道分多个小文件,使用hash函数分流,把无符号整数分到多个小文件,然后统计
法二:用两个bit表示一个数字出现的状态,11表示出现两次以上

补充:
使用题目1的int[]不断统计

  1. 一个10G文件,存储的无符号int,现在变成一个新文件,有序且只有5G内存,怎么实现
    解:
    组织一个小根堆,存储记录包括存储的内容和词频,即一条记录8字节,考虑到可能有一些额外损耗,我们假设一条记录16字节,根据词频组织小根堆。
    5G/16字节,大概支持 2 27 2^{27} 227条记录,将 2 32 2^{32} 232的数字(无符号整数的总量)分到 2 27 2^{27} 227记录中,即每个记录中应该表示2^5个数字。

  2. 在这里插入图片描述
    在这里插入图片描述
    n^1表示反转(n只能是0或1)
    上述的方法可能存在a-b溢出的情况
    改进:
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
是2的幂表示只有一个1
法1:
A&(~A+1)获得二进制最右侧的1
法2:
x&(x-1)==0
在这里插入图片描述
是4的幂表示只有一个1且在偶数位
在这里插入图片描述
先判断x是不是只有一个1,即是不是2的幂,
然后:
在这里插入图片描述
如果等于0则不是4的幂
在这里插入图片描述
0x5555555就是32位0101…01
7. 在这里插入图片描述

  • 加法
    异或:无进位相加
    与运算左移一位:进位信息
    两者相加即实现了加法,但由于不可以使用加法,因此不断重复两个数求异或和与运算左移一位的结果,最后当其无进位相加信息是000000…时,与的结果就是加法的结果
    在这里插入图片描述
    在这里插入图片描述

  • 减法
    第二个数变成加法的相反数
    在这里插入图片描述

  • 乘法
    在这里插入图片描述
    在这里插入图片描述

  • 除法
    乘法的逆运算
    选择(x>>i)>=y而不是x>(y<<i),因为左移可能溢出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值