目录
位运算
位运算的技巧淫技
判断奇偶性 x&1=1(奇),x&1=0(偶),奇数的二进制最后一位是1,偶数为0
获取二进制位是1还是0
交换两个整数变量的值
不用判断语句,求整数的绝对值
异或 可以理解为不进位的加法: 1+1=0,0+0=0,1+0=1
性质
交换律 可任意交换运算因子的位置
结合律 (a^b)^c=a^(b^c)
对于任何数x,都有x^x=0,x^0=x,同自己求异或为0,同0求异或为自己
自反性A^B^B=A^0=A,连续和同一个因子做异或运算,最终结果为自己
位运算符
在处理整形数值时,可以直接对组成整形数值的各个位进行操作。这意味着可以使用屏蔽技术获取整数中的各个位
&与,|或,^异或,~非
(>>)和<<运算符将二进制位进行右移或者左移
(>>>)运算符将用0填充高位;>>运算符用符号位填充高位,没有<<<运算符
对于int类型,1<<35和1<<3是相同的,而左边的操作数是long型时需要对右侧操作数模64
a | b | ~a | a&b | a|b | a^b |
---|---|---|---|---|---|
1 | 1 | 0 | 1 | 1 | 0 |
0 | 1 | 1 | 0 | 1 | 1 |
0 | 0 | 1 | 0 | 0 | 0 |
题1:找出唯一成对的数
1-1000着1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
public class 唯一成对的数{
public static void main(String [] args){
int N=1001;
int[]arr=new int[N];
for(int i=0;i<arr.length-1;i++){
arr[i]=i+1;
}
//最后一个是随机数
arr[arr.length-1]=new Random().nextInt(N-1)+1;//0-1001之间,包括1000
int index = new Random().nextInt(N);//0-1000之间
Util.swap(arr,index,arr.length-1);
Util.print(arr);
int x1 =0;
for(int i=0;i<N-1;i++)
{
x1=(x1^i);
}
for(int i=0;i<N;i++)
{
x1=x1^arr[i];
}
System.out.println(x1);
}
}
方法2
int [] helper = new int[4];
for(int i=0;i<N;i++0)
{
helper[arr[i]]++;
}
for(int i=0;i<N;i++)
{
if(helper[i]==2)
{
System.out.println(i);
break;
}
}
题2:找出落单的数
一个数组里面除了某一个数字之外,其他的数字都出现两次,请写程序找出之歌只出现一次的数字
* 连续异或就可以求出落单数 *
二进制中1的个数
请实现一个函数,输入一个整数,输出改数二进制表示中1的个数
列如 9的二进制1001,有2位是1
public class _02_1的个数{
public static void main[String[]args]
{
Scanner in = new Scanner(System.in);
int N =sc.nextInt();
int count=0;
//比对每一位
for(int i=0;i<32;i++)
{
if(N&(1<<i)==(1<<i))
{
count++;
}
}
System.out.println(count);
}
}
---------------------------------------
count = 0;
while(N!=0)
{
N=((N-1)&N);//消除低位1
count++;
}
题4:是不是2的整数次方
用一条语句判断一个整数是不是2的整数次方
2的整数次方其二进制只有一个是1其余为0
if(((x-1)&x)==0)
题5:将整数的奇偶位互换
private static int m(int i){ int ou=i&0xaaaaaaa;//和1010 1010 1010...做与运算取出偶数位,保留偶数位 int ji=i&0x5555555;//和0101 0101 0101...做与运算取出奇数位,保留奇数位 return (ou>>1)^(ji<<1);//交换 连起来 }
题6 :0~1间浮点实数的二进制表示
给定一个介于0和1之间的实数,如0.625,类型为double,打印它的二进制表示(0.101,因为小数点后的二进制分别表示为0.5,0.25,0.125...)
如果该数字无法精确地用32位以内地二进制表示,则打印“ERROR”
public class _06_二进制小数{ public static void main(String [] args){ double num = 0.625; StringBuilder sb = new StringBuilder("0."); while(num>0){ //乘2,挪整 double r= num*2; //判断整数部分 if(r>=1) { sb.append("1"); //消除整数部分 num=r-1; } else{ sb.append("0"); num=r; } if(sb.length()>34){ System.out.println("ERROR"); return; } } System.out.println(sb.toString()); } }
题7:出现k次与出现1次
数组中只有一个数出现了1次,其他的数都出现了k次,请输出只出现了一次的数
思路:2个相同的2进制数做不进位加法,结果为0,10个相同的10进制数做不进位加法,结果为0,k个相同的k进制数不进位加法,结果为0
任意进制互转
手工取余
Integer.toString(i,radix);