2021年1月28日--位运算

本文介绍了如何使用位运算来解决一个算法问题:在一个包含1到1000的数组中,有一个数字出现了两次,其余各不相同,如何在只访问每个元素一次且不使用额外空间的情况下找到这个重复的数字。文章通过位运算的异或操作展示了如何消除相同元素并找到重复的数字,同时讲解了位运算的相关知识,包括位逻辑运算符和位移运算符。
摘要由CSDN通过智能技术生成

2021年1月28日–算法

视频教程:

https://www.bilibili.com/video/BV1KA411x7oA?from=search&seid=9102962925755536138

https://www.bilibili.com/video/BV14x411L7zh?from=search&seid=15891911922191337389

知识

1.位运算

1.位逻辑运算符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-czXnn4yM-1611845908843)(C:\Users\31677\AppData\Roaming\Typora\typora-user-images\image-20210128145144871.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A61g4m37-1611845908849)(C:\Users\31677\AppData\Roaming\Typora\typora-user-images\image-20210128145258005.png)]

2.位移运算符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DytcGywy-1611845908853)(C:\Users\31677\AppData\Roaming\Typora\typora-user-images\image-20210128145033417.png)]

练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gtHIuBW5-1611845908859)(C:\Users\31677\AppData\Roaming\Typora\typora-user-images\image-20210128222342990.png)]

实践

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

package test20210128;
import java.util.Random;

public class Demo1 {
    //swap函数用于交换数组中的元素位置
    public static void swap(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    public static void main(String[] args) {
        int N = 1001;//该数组长度为1001
        int[] arr = new int[N];
        //对数组元素的前十个进行赋值
        for(int i = 0;i<arr.length-1;i++){
            arr[i]=i+1;
        }
        //对数组最后一个元素赋值为一个1-10之间的随机数
        arr[arr.length-1] = new Random().nextInt(N-1)+1;
        //创建一个变量,赋值为0-10之间的随机数,该变量是一个下标,用于交换元素位置时使用
        int index = new Random().nextInt(N);
        //对数组arr交换下标为index的元素和下标为length-1的元素
        swap(arr,index,arr.length-1);
        //输出数组
        for(int i=0;i<arr.length;i++){
            System.out.print(arr[i]+" ");
        }
        System.out.println();
        //int N = 11;
        //异或运算中任何数字与0进行异或运算都得到该数字本身
        //异或运算满足结合律(即(a^b)^c == a^(b^c))
        //对于任何数x,都有x^x=0,所以该寻找重复数的方法是通过异或进行相同元素的消除,同时剩下的就是要寻找的多余的数
        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.位运算实际是16位或者32位或者64位二进制表示的数字进行运算的结果

拓展:

1.同时还有无符号左移(右移)

2.可以用这种方法进行消除操作,A^A=0

3.任何数与0异或操作都得到这个数本身

例如:0^1=1 1^1=0 23=1(010011=001) 0^5=5

2.注意short和byte型的数属于低精度数,不适合做无符号位运算(<<<或者>>>)

参考博客:

https://blog.csdn.net/sinat_35121480/article/details/53510793

的数属于低精度数,不适合做无符号位运算(<<<或者>>>)

参考博客:

https://blog.csdn.net/sinat_35121480/article/details/53510793

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值