- 类型基础
计算机中最小单位的内存是bit,只可以表示0,1
1Byte=8bit
1int=4byte 32bit
Float=4byte 32bit
Long=8byte 64bit
Char 2byte 16bit - Int a= 1,这个1在计算机中是怎么存储的?
0000 0000 0000 0000 0000 0000 0000 0001 toBinaryString(1)=1
前面31位补0
左移<<:1 << 2(位) = 2 乘 2 = 4 公式:2^n次幂 n表示移动的位数
实例:
数字1:0000 0000 0000 0000 0000 0000 0000 0001
左移2:0000 0000 0000 0000 0000 0000 0000 0100
右移>>:4 >> 2(位) = 4/2 乘2 = 1 公式:k/2^n次幂 n表示移动的位数,k表示需要移动的数字
数字4:0000 0000 0000 0000 0000 0000 0000 0100
右移2:0000 0000 0000 0000 0000 0000 0000 0001
位与 &:同位上的两个数都是1则位1,否则为0
位或 |:同为上的两个数只要有一个为1 则为1,否则为0 - 如何在3亿个整数(0~2亿)中判断某一个数是否存在?内存限制500M,一台机器。
采用int来解决:
1个int有32位bit;
二进制表示: 0000 0000 0000 0000 0000 0000 0000 0000
每个数是否存在就把0置为1;
所以一个int数字就可以表示32个数字是否存在;
那2亿个数字用int数组存下来所需要的空间:2亿4Byte/1024/1024 = 762M
如果是bitMap:2亿/324Byte/1024/1024=23M(因为我们最后还是会用int来表示bit),只不过我们开了int data[max/32+1],这里加一是因为整数相除会取整,如果除不下,需要多一个数组来存放;
数组的大小data[2亿/32+1]
计算再那个数组下:查找的数字/32 = 数组下标
计算数组中的那个位置:查找的数字%32 = 数字所在数组的下标 - 位运算
与或非异或:
与:同时为1则为1;
或:有一个为1则为1;
非:取反;
异或:相同为零,相异为1,即 0 ^ 1 = 1,0 ^ 0 =0,1 ^ 1 = 0;
取反:~
举例:
1byte等于8位二进制,使用byte新增,查询,删除,下标为6的数据,二进制是:0100 0000换算成十进制等于64
下面的计算:首先需要把1左移6为得到(下标从0开始):0100 0000
新增:设置byte数据中的二进制位为1方式,或
0000 0000
0100 0000 或运算得到0100 0000
查询:判断byte数据在二进制位是否为1,与
0100 0000
0100 0000 与运算等到 0100 0000
如果等于0表示不存在,否则存在,因为1&1等于1,否则全是0
删除:
0100 0000
0100 0000 异或运算得到0000 0000
取模:
8%8 = 8 & 8-1;
8:0000 1000
7:0000 0111 - 应用
(1)数据判重
(2)对没有重复的数据进行排序 - BitMap算法的缺点
(1)数据不能重复
(2)数据量少时相对于普通的hash没有优势
(3)无法处理字符串:hash冲突 - BiMap算法的代码,
public class BitMap {
int[] intData;
int max;
public BitMap(int max) {
this.max = max;
//max >> 往右移动3位 2*2*2=8,+1是因为取整的原因,需要把多余数部分的数据再开辟一个数组
intData = new int[(max >> 5) + 1];
}
public void addInt(int number) {
int array = number >> 5;
int loc = number & 32-1;
//接下来就是要把bit数组里面的 bisIndex这个下标的byte里面的 第loc 个bit位置为1
//把1向左移动loc位,然后与data[loc]做或运算,就会把loc下标的0置为1
intData[array] |= 1 << loc;
}
public boolean findInt(int number) {
//除以8
int array = number >> 5;
int loc = number & 32-1;
//如果原来的那个位置是0 那肯定就是0 只有那个位置是1 才行
int flag = intData[array] & 1 << loc;
if (flag == 0) return false;
return true;
}
public void delInt(int number) {
int array = number >> 5;
int loc = number & 32-1;
//删除,异或^或者使用~取反
intData[array] = ~1 << loc;
}
public static void main(String[] args) {
BitMap bitMap = new BitMap(200000001); //10亿
bitMap.addInt(2);
bitMap.addInt(3);
bitMap.addInt(65);
bitMap.addInt(66);
System.out.println(bitMap.findInt(3));
System.out.println(bitMap.findInt(65));
bitMap.delInt(65);
System.out.println(bitMap.findInt(65));
}
}