位运算

位运算符

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<N-1;i++){
            arr[i]=i+1;    
        }
        int randNum=new Random().nextInt(N);   //生成一个随机数放在最后一位
        arr[N-1]=randNum;
        int index=new Random().nextInt(N-1);   //抽取一个数与最后一个数交换位子
        swap(arr,index,N-1);
        for(int n:arr)
            System.out.print(n+", ");   //打印函数用来确认结果是否正确
//设x先做1到N的异或,再与数组中的元素做异或,最后剩下的数(做了奇次异或)被赋给了x;
       int x=0;
        for(int i=1;i<=N-1;i++)   
            x=x^i;
        for(int j=0;j<N;j++)
            x=x^arr[j];
        System.out.println();
        System.out.println(x);
    }
    static void swap(int[] arr,int index1,int index2){
        int temp=arr[index1];
        arr[index1]=arr[index2];
        arr[index2]=temp;
        }
    }

例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");
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容