蓝桥杯笔记之位运算篇

位运算

最近刷了几道算法题,有一些是和位运算有关的,虽然位运算在源码中较多的出现,但个人仍认为其实操意义不大。不过不得不说,基于位运算的一些算法处理,有时候确实很神奇。因此做一个记录。

1. 异或:^, x ^ x=0, x ^ 0=x, x ^ 全1= ~x
2. 与 : & , x & x=x,x & 0=0,x & 1=x
3. 或:|,x | x=x,x |0=0,x | 1=x;
4. 取反:~
5. 左移:<<;移动一位:x<<=1;
6. 右移:>>

例题:

1~1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?

public static void main(String[] args) {
        int N=1001;
        int []arr=new int[N];
        for(int i=1;i<N-1;i++){
            arr[i]=i+1;
        }
        arr[N-1]=new Random().nextInt(N-1)+1;

        int x1=0;
        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);
    }

二进制中1的个数(一题三解)

public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int N=sc.nextInt();
        System.out.println(Integer.toString(N,2));
        int count=0;
//        //1.第一种方式
//        for(int i=0;i<32;i++){
            if((N&(1<<i))==(1<<i)){
                count++;
            }
//            //第二种方式
//            if(((N>>>i)&1)==1){
//                count++;
//            }
//        }
        while(N!=0){
            N=(N&(N-1));
            count++;
        }

        System.out.println(count);
    }

交换一个数的二进制的奇偶位

public static void main(String[] args) {
        int x=6;
        System.out.println(Integer.toString(x,2));
        System.out.println(Integer.toString(fun1(x),2));
    }

    public static int fun1(int x) {
        int a = x & 0xaaaaaaaa;//1010 1010
        int b = x & 0x55555555;//0101 0101
        return (a>>1)^(b<<1);
    }

数组中只有一个属出现了1次,其它的数都出现了k次,请输出只出现一次的数

public static void main(String[] args) {
        int[]arr={2,2,2,9,7,7,7,3,3,3,6,6,6,0,0,0};
        int len=arr.length;
        char[][] radix=new char[len][];
        int k=3;

        int maxlen=0;
        for(int i=0;i<len;i++){
            radix[i]=new StringBuilder(Integer.toString(arr[i],k)).reverse().toString().toCharArray();
            if(radix[i].length>maxlen){
                maxlen=radix[i].length;
            }
        }

        int[] resArr=new int[maxlen];
        for(int i=0;i<len;i++){
            for(int j=0;j<maxlen;j++){
                if(j>=radix[i].length){
                    resArr[j]+=0;
                }else{
                    resArr[j]+=(radix[i][j]-'0');
                }
            }
        }

        int res=0;
        for(int i=0;i<maxlen;i++){
            res+=(resArr[i]%k)*(int)(Math.pow(k,i));
        }
        System.out.println(res);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值