一、位运算
用1做&是保留,用0做&是消除
- 具体应用
- 判断奇偶数
- x & 1 == 0为偶, ==1 为奇(偶数最后一位为0,奇数最后为1
- 获取某个数x 二进制形式上的第a位是0or1
- x>>(a-1) & 1
- x & 1<<(a-1)
- 交换两个整数变量的值
- int a=1,b=2;
- 判断奇偶数
a=a^b;
b=a^b;
a=a^b;
异或性质
- 交换律
- 结合律
- 对任何数, x^x = 0 ,x ^0 = x,与自己求异或为0,同0求异或为自己
- 自反性 A^B^B = A^0=A

- 思路:直接全部异或上(1^2^…^1000)最后出来的那个数就是重复的x
- 理由:x^x^A = A,所以所有的都重复两遍,那么重复的那个就是三遍,就是仍然是本身。

- 思路:和上一题一样,之间再异或两次次,那么某一个数字就是异或三次,其余的都是异或六次变成0.
- 理由:x^x^A = A

思路:
直接变成二进制的,然后一个个数到底有多少个
- 第一种是挪动1
- 第二种是挪动x(忽略符号,高位补0的形式),和1进行比较
//方法1public int howMany1_1(int x){int count = 0;for(int i = 0;i < 32 ; i++ ) {//eg. 00100和00001,00010...逐个进行比较,看是否== 00001,00010...if ( (x & (1<<i)) == (1<<i)){count++;}}return count;}//方法2public int howMany1_2(int x){int count = 0;for(int i = 0;i < 32 ; i++ ) {//eg. 00100变成00010,00001之后和00001逐个进行比较,看是否==if ( ((x>>>i) & 1) == 1){count++;}}return count;}
(x-1) & x 可以将x的低位的1去掉,最终只要看做了几次这样的运算
- 举例:x = 10100 , x-1 = 10011,那么 (x-1) & x = 10000,就相当于去掉了一个1.
public int howMany1_3(int x){int count = 0;//这里,如果x是0,则无1,若x>0,则一定有1,那么就是从1开始计算,不用考虑无1的情况while(x != 0){x = (x-1)&x;count++;}System.println.out(count);return count;}
- 举例:x = 10100 , x-1 = 10011,那么 (x-1) & x = 10000,就相当于去掉了一个1.

- 思路:找规律,2的整数次方的二进制内只有一个1.再结合第三题。
一些&的题目
- 将整数的奇/偶位互换
eg:9 :1001 ,互换后为0110,是6,(指12位换,34位换)- 思路:把奇数位取出来,把偶数位取出来,然后一个偶数往右,奇数往左,一个异或就行
把奇数位取出的方法:将x 和0101010101做&运算。由&来保留所有的奇/偶数位
eg: 1001&0101 = 0001,只保留了奇数项,偶数项全为0(保留偶数项同理,将其与1010&)//代码就很简单了int ouShu = 0xaaaaaaaa & x;int jiShu = 0x55555555 & x;return (ouShu>>1) ^ (jiShu<<1)
- 思路:把奇数位取出来,把偶数位取出来,然后一个偶数往右,奇数往左,一个异或就行
- 将整数的奇/偶位互换

- 首先分析整数的变成二进制的方法:不断对2取模,然后/2,往前面放。
eg:10是1010,先%2余0再/2变成5,然后%2余1再/2变成2,然后%2余0再/2变成1,然后%2余1再/2变成0.最后是从右向左排列。 - 然后分析小数的取法:比如0.625,先2变成1.25,取1,再0.252 = 0.5,取0,再0.5*2 = 1,取1,结束
public static void BinaryFloat(double x) {StringBuilder s = new StringBuilder("0.");//此处条件换成x>0也可。while (x != 0) {//乘二x = x * 2;//取整if (x >=1){x = x-1;s.append("1");}else s.append("0");}//如果长度大于32位(加上0.之后就是34位if (s.length() > 34) {System.out.println("ERROR");return;}System.out.println(s);}
- 首先分析整数的变成二进制的方法:不断对2取模,然后/2,往前面放。

汉诺塔问题
- 结论:Hn = 2^n - 1(次数)
- 思路:一根柱子为辅,另外两个柱子上是目标柱和原始柱。
//help为辅助的柱子(就是在函数调用时一开始为空的柱子//from为起始//to为终点//N为数量public static void printHanoiTower (int N,String from,String to,String help){if(N==1){System.out.println("将"+N+""从+from+"移动到"+to+"辅助为"+help);}else {printHanoiTower(N-1 ,from ,help,to);//移到辅助的柱子上System.out.println("将"+N+""从+from+"移动到"+to+"辅助为"+help);//最底下那个盘移到目标柱上printHanoiTower(N-1 ,help ,to,from);//移到目标上}}

