1.位运算基本概念
2.位运算判断奇偶数
3.对应练习题
题目一:
完成此题目建立了两个类
本题关键思路:
A^A=0
B^0=B
代码说明以及注释:
package lanqiaobei;
import java.util.Random;
/**
* @author 23604
*/
public class WeiYunSua {
public static void main(String[] args) {
int N = 11;
//创建一个字符串
int[] arr = new int[N];
//遍历数组
for (int i = 0; i < arr.length; i++) {
arr[i] = i + 1;
}
//生成随机数从0到N-1不包括N,末尾加1使其变成生成从1到N的随机数并将其放在数组末尾
arr[arr.length - 1] = new Random().nextInt(N - 1) + 1;
//生成随机数组下标
int index = new Random().nextInt(N);
//把末尾的随机数与随机下标指的数组的值互换
Util.swap(arr, index, arr.length - 1);
//打印数组
Util.print(arr);
//x1初始化
int x1 = 0;
//使x1=1^2^3^4^5.......
for (int i = 1; i <= N - 1; i++) {
x1 = (x1 ^ i);
}
//相乘消去相同的
for (int i = 0; i < N; i++) {
x1 = x1 ^ arr[i];
}
System.out.println(x1);
}
}
package lanqiaobei;
public class Util {
static void swap(int arr[], int a, int b) {
int t = 0;
t = arr[a];
arr[a] = arr[b];
arr[b] = t;
}
static void print(int arr[]) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if(i==arr.length-1){
System.out.println(arr[i]+"]");
}
else {
System.out.print(arr[i] + ",");
}
}
System.out.println();
}
}
题目二:
解题思路:该接替思路与第一题相同。
代码如下:
package lanqiaobei01;
import java.util.Scanner;
/**
* @author 23604
*/
public class Ti2 {
public static void main(String[] args) {
int N = 11;
System.out.println("请输入"+N+"个数,里边只有一个数不是两个相等:");
Scanner sc = new Scanner(System.in);
int[] arr = new int[N];
for (int i = 0; i < N; i++) {
arr[i] = sc.nextInt();
}
Util1.print(arr);
int x1=0;
for(int i=1;i<=N; i++){
x1=(x1^arr[i-1]);
}
System.out.println(x1);
}
}
package lanqiaobei01;
public class Util1 {
static void print(int arr[]) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if(i==arr.length-1){
System.out.println(arr[i]+"]");
}
else {
System.out.print(arr[i] + ",");
}
}
System.out.println();
}
}
题目三:
解法一:
解题思路:
让1位移,位移到的那位与输入的数字对应的那位做与运算
1 | 0 | 0 | 1 |
---|---|---|---|
0 | 0 | 0 | 1 |
N&(1<<0):
1 | 0 | 0 | 1 |
---|---|---|---|
0 | 0 | 0 | 1 |
N&(1<<0)=1=1<<0
count++
N&(1<<1):
1 | 0 | 0 | 1 |
---|---|---|---|
0 | 0 | 1 | 0 |
N&(1<<1)=0!=1<<1
N&(1<<2):
1 | 0 | 0 | 1 |
---|---|---|---|
0 | 1 | 0 | 0 |
N&(1<<2)=0!=1<<2
N&(1<<3):
1 | 0 | 0 | 1 |
---|---|---|---|
1 | 0 | 0 | 0 |
N&(1<<3)=1=1<<3
count++
代码实现如下:
package lanqiaobei01;
import java.util.Scanner;
/**
* @author 23604
*/
public class Ti3 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个数:");
int N=sc.nextInt();
System.out.println("转为二进制数是:"+Integer.toString(N,2));
int count=0;
for(int i=0;i<32;i++){
if((N&(1<<i))==(1<<i)){
count++;
}
}
System.out.println("1的个数为:"+count);
}
}
解法二:
解题思路:
假如N为6
N&( N-1)
0 | 1 | 1 | 0 |
---|---|---|---|
0 | 1 | 0 | 1 |
得到:
0 | 1 | 0 | 0 |
---|
与运算起到消除末位1的作用,消除几次就有几个1
代码演示如下:
package lanqiaobei01;
import java.util.Scanner;
/**
* @author 23604
*/
public class Ti3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个数:");
int N = sc.nextInt();
System.out.println("转为二进制数是:" + Integer.toString(N, 2));
int count = 0;
while (N != 0) {
N = N & (N - 1);
count++;
}
System.out.println("1的个数为:" + count);
}
}
题目四:
解题思路:
与题目三解法二相似,并且若是整数2的整数次方二进制表示只有一个1
代码演示如下:
package lanqiaobei01;
import java.util.Scanner;
/**
* @author 23604
*/
public class Ti4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数:");
int N = sc.nextInt();
int count = 0;
while (N != 0) {
N = N & (N - 1);
count++;
}
if (count != 1) {
System.out.println("该数不是偶数");
} else {
System.out.println("该数是偶数");
}
}
}
题目五:
解题思路:
以9为例
1 | 0 | 0 | 1 |
---|---|---|---|
0 | 1 | 0 | 1 |
让9和奇数位为1,偶数位为0的数做与运算,与0做与相当于清除,与1做与相当于保留。与运算结果为:
0 | 0 | 0 | 1 |
---|
此时发现奇数位上原来是什么现在还是什么。
再让9和奇数位为0,偶数位为1的数做与运算,与0做与相当于清除,与1做与相当于保留。
1 | 0 | 0 | 1 |
---|---|---|---|
1 | 0 | 1 | 0 |
与运算结果为:
1 | 0 | 0 | 0 |
---|
此时发现偶数位上的原来是什么现在还是什么。
将保留奇数的左移一位和保留偶数的右移一位做异或运算
0 | 0 | 1 | 0 |
---|---|---|---|
0 | 1 | 0 | 0 |
运算结果为:
0 | 1 | 1 | 0 |
---|
完成奇偶换位
代码演示如下:
package lanqiaobeisuanfa01;
/**
* @author 23604
*/
public class Ti5 {
public static void main(String[] args){
int a=9;
int b=m(9);
System.out.println("a的值为:"+a);
System.out.println("b的值为:"+b);
}
private static int m(int i){
//十六进制a=1010
int ou=i&0xaaaaa;
//十六进制5=0101
int ji=i&0x55555;
return (ou>>1)^(ji<<1);
}
}
题目六:
解题思路:
小数位二进制十进制转化为二进制
以0.625为例:n=0.625*2=1.25>1,二进制上填一个1,抹除整数位的1,变成0.25
1 |
---|
n=0.25*2=0.5<1,填0
1 | 0 |
---|
n=0.5*2=1.0=1,填1,抹除整数位1,
1 | 0 | 1 |
---|
则0.625转化成二进制为0.101
代码演示:
package lanqiaobeisuanfa01;
/**
* @author 23604
*/
public class Ti6 {
public static void main(String[] args) {
//StringBuilder中append 方法始终将这些字符添加到生成器的末端
StringBuilder sb = new StringBuilder("0.");
double num = 0.625;
while (num > 0) {
double r = num * 2;
if (r >= 1) {
sb.append("1");
num = r - 1;
} else {
sb.append(0);
num=r;
}
//总共32位,加上StringBuilder sb = new StringBuilder("0.");中的0.后长度为34
if (sb.length() > 34) {
System.out.println("ERROR");
return;
}
}
System.out.println(sb.toString());
}
}
题目七:
解题思路:
k进制的k个数相加,如果不进位的话等于0.
以三进制5+5+5为例:
1 | 2 |
---|---|
1 | 2 |
1 | 2 |
1+1+1=3
2+2+2=6
为3的倍数不进位肯定等于0