位运算

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位运算相关的知识,希望对你有一定的参考价值。

1.位运算介绍   

    程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作


2.位运算符号

技术分享图片

Java中的运算符号

    & : 按位与

    | :按位或

    ^ :按位异或

    ~ :按位取反

    << :左移,右侧补0

    >> :右移,左侧补符号位

    >>> :右移,左侧补0


3.应用

3.1 Excel表格问题

    在Excel中,用A表示第1列,B表示第2列......Z表示第26列,AA表示第27列,AB表示第28列......以此类推。请写出一个函数,输入用字母表示的列号编码,输出它是第几列:

解析:

    A=1,B=2,C=3,......,Z=26

    AA=(26^0 * 1) + (26^1 * 1) = 27;   注:^表示次方这里

    AB=(26^0 * 2) + (26^1 * 1)= 28;


3.2 交换两个数字

    在不使用额外空间的情况下交换两个数字:

解析:

一般解法:

技术分享图片

位运算解法:

技术分享图片


3.3 比较练习

    对于两个32位整数a和b,请设计一个算法返回a和b中较大的。但是不能用任何比较判断。若两数相同,返回任意一个。

public:
	int Flip(int c)
	{
		return c^1;
	}
	int GetSign(int c)//非负为1,负为0.
	{
		return Flip((c>>31)&1);
	}
	int getMax(int a, int b) 
	{
		int c=a-b;
		int as=GetSign(a);//a的符号,as==1表示a为非负,as==0表示a为负
		int bs=GetSign(b);//b的符号,bs==1表示b为非负,bs==0表示b为负
		int cs=GetSign(c);//a-b的符号
		int difab=as^bs;//表示a和b是否符号不相同,不相同为1,相同为0
		int sam=Flip(difab);//表示a和b是否符号相同,相同为1,不相同为0
		if(sam)
			return cs?a:b;
		else
			return (as-bs)?a:b;
	}
};


3.4 寻找奇数出现次数

    有一个整型数组A,其中只有一个数出现了奇数次,其他的数都出现了偶数次,请打印这个数。要求时间复杂度为O(N),额外空间复杂度为O(1).

解析:

给定一个eo和一个已知数组,然后用eo与数组每个元素进行异或运算。

技术分享图片

需要了解的是:任意调换整数异或的顺序不会改变最终的异或值:

技术分享图片

所以最终的异或结构为:eo = D;













以上是关于位运算的主要内容,如果未能解决你的问题,请参考以下文章

编程思想:巧用位运算重构代码

基础位运算基本原理和应用

位运算相关

优雅代码05-从hashMap源码介绍位运算符

c语言位运算问题?

为啥 JSHint 反对位运算符?我应该如何表达这个代码?