一、基本知识(针对二进制)
1.&:全一则一
2.|:有一则一
3.^:在二进制中,相异为一,相同为0(可理解为不进位加法:1^1=0 1^0=1)
概括起来就是:符合交换律、结合律、相反性(x^x=0,x^0=x,x^y^y=x【可去重】)
4.~:非运算/取反
5.>>、<<:(带符号)右移、左移,符号后面的表示移动的位数(对于int型(32位),1<<35和1<<3一样的,其中35%32=3,对于long型,需对右侧操作数%64)【为正补0,为负补1】
6.有>>>而无<<<:最高位补0
二、应用:
1.判断奇偶:x&1=1为奇数,x&1=0为偶数
2.获取二进制位是1还是0:1&1=1,1&0=0,0&1=1,0&0=0
3.交换两个整数变量的值:
int temp = a^b;
a = a^temp;
b = b^temp;
4.不用判断语句,求整数的绝对值:
首先要知道求负数:~x+1= -x
例如:-7的绝对值7是111,即0000 0000 0000 0000 0000 0000 0000 0111,取反码转换为1111 1111 1111 1111 1111 1111 1111 1000,然后 +1——》1111 1111 1111 1111 1111 1111 1111 1001
因为>>/<<是带符号的位运算,正数移动后补0,符数移动后补1
求绝对值:
int i = a>>31;//第32位是符号位,0为正数,1是负数,找正负
return ((a^i)-i);//任何数x^0=本身(说明正数)
参考:https://www.cnblogs.com/dyllove98/archive/2013/08/04/3236802.html
题目:1~1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其他均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
import java.util.Arrays;
import java.util.Random;
public class blue01 {
public static void main(String[] args) {
int N = 1001;
int all = 0, sum = 0;
int[] arr = new int[N];
for (int i = 0; i < arr.length - 1; i++) {
arr[i] = i + 1;
all += arr[i];
}
arr[arr.length - 1] = new Random().nextInt(N - 1) + 1;
all += arr[arr.length - 1];
System.out.println(all);
System.out.println(Arrays.toString(arr));
for (int i = 1; i < arr.length; i++) {
sum += i;// 0+1+2+3...+1000
}
System.out.println(sum);
int x = all - sum;
System.out.println(x);
// 上面用的是不借助辅助空间,以下是借助辅助空间
System.out.println("***********");
int[] helper = new int[N];
for (int i = 0; i < N; i++) {
helper[arr[i]]++;// 开辟一个数组来存储元素出现的次数
if (helper[arr[i]] == 2) {// 由题可知,次数大于2的即为重复的数 System.out.println(arr[i]);
}
}
System.out.println(Arrays.toString(helper));
}
}
还可以采用等差数列的方法
import java.util.Arrays;
import java.util.Random;
public class blue01 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
int N = 1001;
int all = 0, sum = 0;
;
int[] arr = new int[N];
for (int i = 0; i < arr.length - 1; i++) {
arr[i] = i + 1;
all += arr[i];
}
arr[arr.length - 1] = new Random().nextInt(N - 1) + 1;
all += arr[arr.length - 1];
System.out.println(all);
System.out.println(Arrays.toString(arr));
for (int i = 1; i < arr.length; i++) {
sum += i;// 0+1+2+3...+1000
}
System.out.println(sum);
int x = all - sum;//减法运算得到的数为重复的数
System.out.println(x);
}
}
补题:
整数转换。编写一个函数,确定需要改变几个位才能将整数A转成整数B。
示例1:
输入:A = 29 (或者0b11101), B = 15(或者0b01111)
输出:2
示例2:
输入:A = 1,B = 2
输出:2
画图更理解一些
public class ConvertIntegerIcci0506 {
public static void main(String[] args) {
System.out.println(convertInteger(29, 15));
}
static public int convertInteger(int A, int B) {
int temp = A ^ B;
System.out.println(temp);
int count = 0;
while (temp != 0) {
temp &= (temp - 1);// 去掉二进制表示的最右边的1
count++;
}
return count;
}
}