位图
位图能极大地压缩空间
基本实现
public static class bitMap{
private long[] bits;//long型是64位的
public bitMap(int max){
bits=new long[(max+64)>>6];//右移6位相当于除以64 (max+64)/64
}
public void add(int num){
//num/64-->哪个整数
//num%64-->num&63
bits[num>>6]|=(1L<<(num&63));//1L代表long的1(64位)
}
public void delete(int num){
bits[num>>6]&=~(1L<<(num&63));
}
public boolean contains(int num){
return (bits[num>>6]&(1L<<(num&63)))!=0;
}
}
二进制运算中,异或运算就是无进位相加
二进制运算的进位信息可用** (a&b)<<1 **得到
位运算实现加减乘除
异或:a^b 同或:(a ^ b)^1
或:| a|=1<<i(可将第i位置为1)
public static int add(int a,int b){
int sum=0;
while (b!=0){//一直有进位信息就重复,直到没有进位信息
sum=a^b;// a与b的无进位加法
b=(a&b)<<1;//进位信息
a=sum;
}
}
//a-b=a+(-b)=a+(~b+1)=a+add(~b,1)=add(a,add(~b,1))
public static int minus(int a,int b){
return add(a,add(1,~b));
}
public static int multi(int a,int b){
int res=0;
while (b!=0){
if ((b&1)!=0){//判断b的末位是否为1,是1,就把a加进去
res=add(res,a);
}
a<<=1;
b>>>=1;//不带符号右移1位,将比较过的移出去
}
return res;
}
//a,b都不是系统最小值
public static int div(int a,int b){
int x=(a<0)?(add(~a,1)):a;//若a为负数,则将a变为正数
int y=(b<0)?(add(~b,1)):b;
int res=0;
for(int i=30;i>=0;i=minus(i,1)){//i--
if ((x>>i)>=y){//x右移去够y,y左移可能会出现符号位由0变1,溢出
res|=1<<i;//将i位置为1
x=minus(x,y<<i);
}
}
//res为正数,ab异号,a^b为真,res加负号
return (a>0)^(b>0)?add(~res,1):res;
}
public static int divide(int a,int b){
if(a==Integer.MIN_VALUE&&b==Integer.MIN_VALUE){
return 1;
}
else if (a==Integer.MIN_VALUE){//系统最小值=~(系统最大值+1)
if (b==add(~1,1)){//b==-1
return Integer.MAX_VALUE;//本应为Integer.MAX_VALUE+1,但不存在,故约定为MAX_VALUE;
}
else {
int ans=div(add(a,1),b);//a+1的绝对值即MAX_VALUE,再除以b(结果偏小)
return add(ans,div(minus(a,multi(ans,b)),b));//结果要补偿回来:ans+(a-b*ans)/b
}
}
else if(b==Integer.MIN_VALUE){
return 0;
}
else{
return div(a,b);
}
}