位运算

位运算符

image.png

image.png

例1:找出落单的数。

一个数组中除了某一个数之外,其他的数字都出现了两次,请找出这个数字;
【知识点】相等的数做异或被消掉了(A ^ A ^ B ^ C ^ C=B);
【思考】遍历依次做异或即可。

例2:如何找数组中唯一成对的数?

1-1001这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间。
【知识点】相等的数做异或被消掉了(A ^ A ^ B ^ C ^ C=B)
【思考】一般情况下考虑定义一个数组,用一个for循环解决,list[arr[i]]++;这道题的特点:1、已知其中的1000个数;2、不用辅助存储空间。可以考虑用异或运算实现;在本数组做异或的基础上再与1-1000做异或,这样要找的数做了三次异或,而其它数只做了两次异或。

import java.util.*;
public class Main{
    public static void main(String args[]){
//先构造一个符合题意的数组
        int N=1001;
        int[] arr=new int[N];
        for(int i=0;i

例3:二进制中1的个数

请实现一个函数,输入一个整数,输出该整数二进制表示中1的个数。例:9的二进制表示为1001,有2位是1。
【知识点】1、(N>>>i&1)==1用于判断二进制第i位上是否为“1”;2、N=N&(N-1);可以消掉一个“1”;
【思考】可以遍历依次与1做与运算,数有多少个1;也可以一个一个地消掉1,数要消掉多少个1才能得到0;

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner in=new Scanner(System.in);
        int N=in.nextInt();
        System.out.println(Integer.toString(N,2));  //将int类型的N以二进制输出,这里用来检验结果是否正确
//方法1:将N不断右移
        int count1=0;
        for(int i=0;i<32;i++){     //输入的是int型,所以用的是32
            if((N>>>i&1)==1)
                count1++;
        }
        System.out.println(count1);
//方法2:N&(N-1)可以消掉一个“1”
        int count2=0;
        while(N!=0){
            N=N&(N-1);
            count2++;
        }
        System.out.println(count2);
        }
    }

例4:是不是2的整数次方

用一条语句判断一个整数是不是2的整数次方。
【知识点】N=N&(N-1);可以消掉一个“1”;2的整数次方说明二进制表示中只有一个1。
【思考】那么只要判断1的个数。如果做了一次消除就能得到0,就说明它是2的整数次方。

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner in=new Scanner(System.in);
        int N=in.nextInt();
        System.out.println(Integer.toString(N,2)); 
            if((N&(N-1))==0)
                System.out.println("是的");
        }
   }

例5:将整数的奇偶位交换

一个整数用二进制表示,奇偶位交换
【知识点】1、N&(101010...10),N二进制奇数位上的数字得以保留,N&(010101...01),N二进制偶数位上的数字得以保留。2、用十六进制表示数0x...(因为这里用二进制的话要写32位,太不容易了)
【思考】既然要交换,那么保留奇数位的要右移,保留偶数位的要左移,再做异或运算。

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner in=new Scanner(System.in);
        int N=in.nextInt();
        System.out.println(Integer.toString(N,2));
        int L=N&0x55555555;
        int r=N&0xaaaaaaa;
        int p=(r>>1)^(L<<1);
        System.out.println(Integer.toString(p,2));
        }
    }

例6:0~1间浮点实数的二进制表示

给定一个介于0和1之间的实数(如0.625),类型为double,打印它的二进制表示(0.101),如果该数字无法精确地用32位以内的二进制表示,则打印"ERROR"
【知识点】1、浮点小数如何转换成二进制:小数部分乘以2,如果大于1,则结果的小数部分下一位是1,否则是0,小数部分一直重复此操作,直到得到0;2、StringBuilder 的常用方法
【思考】这就是将知识点1翻译成代码。

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner in=new Scanner(System.in);
        double N=in.nextDouble();
        StringBuilder sb=new StringBuilder("0.");
        boolean flag=false;
        for(int i=0;i<32;i++){
            N*=2;
            if(N>=1){
                sb.append("1");
                N--;
            }
            else
                sb.append("0");
            if(N==0){
                flag=true;
                break;
            }
        }
        if(flag)
            System.out.println(sb.toString());
        else
            System.out.println("error");
    }
}

你可能感兴趣的:(位运算)