秋招准备-算法-位运算(总)


1.对2的指数次方取余--hash的求模实现

        一个数n对2的k次方取余,等于对这个数减一做与运算。

        n%(2^k) = n & (2^k-1)

        所以,在HashMap的源码中,数组的长度不管怎么扩容都要属于2的次方,是因为要确定键值对的桶位时,是用key求出来的hash值,对其长度取余,然后就用到了这个,桶号index = hash & ( length - 1).


2.交换两个数值--异或

        a = a ^b ; b = a ^ b ; a = a ^ b ;

        0异或任何得不变,1异或任何取反,异或自身得0,即异或一个数两次不变。

        异或还可以用来判断两个数符号是否相同,相同得正,不同得负,注意0的情况

        不过交换数值的话,a=a+b;b=a-b;a=a-b; 感觉比较直观。


3.取反--常见计算题

        0对应-1,1对应-2,记住对应关系就行了,正的反的都是这样。

        取反不管符号,直接找对应的数是什么。

        n+1—— -(~n)

        n-1 —— ~(-n)

        -n   —— ~n+1


4.判断一个数的2进制表示中,1的个数

        n&(n-1)会去掉n的二进制中最右边的那个1,因此可以通过这个性质来做。

        这个表达式还能用来判断一个数是否是2的n次方,如果是的话,其结果会为0。

        

5.判断奇偶数

        n&1,很简单,判断最后一位即可。


6.左移右移

        和5一样,如果要手写代码,不妨用进一些能用到的地方。

        箭头指向哪边,朝哪边移。

        >>n右移n位,除2^n,两个箭头是有符号右移,高位会自动补相应的0或1,>>>n是无符号右移,高位补0的。

        所以i=1<<31;(i=-2^31)

               i=i>>>1;(i=2^30)

        <<m左移m位,乘2^m,左移不存在符号问题,低位自动补0.


6.java操作位运算可能用到的方法

        Integer的静态方法toBinaryString(int i),返回i的二进制的字符串表示。

        后续?……

        

        补一个直观二进制合集,编译运行后直观看很容易回想起int的二进制存储形式

    	System.out.println("0:                "+Integer.toBinaryString(0));
    	System.out.println("-1:               "+Integer.toBinaryString(-1));
    	System.out.println("-2^31 (int~-max): "+Integer.toBinaryString(1<<31));
    	System.out.println("2^31-1(int~+max): "+Integer.toBinaryString((1<<31)-1));
    	System.out.println("8:  "+Integer.toBinaryString(8));
    	System.out.println("32: "+Integer.toBinaryString(32));
    	System.out.println("-8: "+Integer.toBinaryString(-8));
    	System.out.println("-32:"+Integer.toBinaryString(-32));


7.对二进制位的操作

        从低位到高位,取n的第m位

            n>>(m-1) & 1

        从低位到高位,将n的第m位置1

            n | (1<<(m-1))

        从低位到高位,将n的第m位置0

            n &  ~(1<<(m-1))


8.&与&&区别

    	int x=0,y=4;
    	for(int z=0;z<3;z++,x++)
    	{
    		if(x>1&++y<10)
    		{	++y;	}
    	}
    	System.out.println(y);

        这道题我一开始想差了,第一时间我想到的考点就是&&运算,如果前面一个false,就不进行后面的判断了,然后我又想到Java里另一个知识点,就是boolean类型不能自动转换成int类型,这就是while(n--)在C++里可以当n次循环,但Java不行的原因,因为n不能被转成boolean当作true.(byte等会先转成int,然后再在int的二进制形式里截取所需长度转回去(如果不是+=这类运算,需要强转))

        所以我一开始以为两个boolean类型不能做&运算,还以为题目出错了。

        结果是我错了,乱用了知识点,忘记了boolean不是一样在底层用1byte来存嘛,那就可以做&运算嘛,并且&的运算是两边都会进行的,结果自然是两边true才为true。所以这题结果是8;如果是&&的话就是6.


9.

    ……

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值