首页 > 其他分享 >异或运算

异或运算

时间:2023-04-16 19:31:44浏览次数:35  
标签:map arr 运算 rightOne int eor 异或 num

基本概念

  1. 异或运算:想同为0,不同为1
  2. 同或运算:想同为1,不同为0

即无进位相加

性质

  1. 0^N == N N^N == 0
  2. 异或运算满足交换律和结合率

即:a^b = b ^ a

(a^b)^c=a^(b^c)

题一、如何不同额外变量交换两个数

int a = a ^ b

int b = a ^ b

int a = a ^ b

题二、一个数组中有一种数出现奇数次

//arr中,只有一种数出现奇数次,其他都是偶数次,打印
public static void printOnceNum(int[] arr){
    int eor = 0;
    for (int i = 0; i < arr.length; i++) {
        eor ^= arr[i];
    }
    System.out.println(eor);
}

题三、怎么把int类型的数,最右侧1提取出来

int rightOne = a & (-a) 

题四、一个数组中有两种数出现奇数次

//arr中,有两个数出现奇数次,其他数出现偶数次
public static void printTwiceNum(int[] arr){
    int eor = 0;
    for (int i = 0; i < arr.length; i++) {
        eor ^= arr[i];
    }
    int rightOne = eor & (-eor);
    int onlyOne = 0;
    for (int i = 0; i < arr.length; i++) {
        if ((arr[i]&rightOne)!=0){
            rightOne ^= arr[i];
        }
    }
    System.out.println(rightOne+" "+(eor ^ rightOne));
}

题五、一个数组中一种数出现k次,其他M次

//一个数组中有一种数出现K次,其他数都出现M次
//M>1,K<M
//找到出现K次的数
//要求额外空间复杂度O(1),时间复杂度O(N)
//普通方法
public static int getKTimesNum(int[] arr,int K,int M){
    HashMap<Integer,Integer> map = new HashMap<>();
    for (int num:arr) {
        if (!map.containsKey(num))
            map.put(num,1);
        else
            map.put(num,map.get(num)+1);
    }
    for (Integer key:map.keySet()) {
        if (map.get(key) == K)
            return key;
    }
    return -1;
}
//使用位运算
public static int getKTimesNum2(int[] arr,int K,int M){
        int[] count = new int[32];
        for (int num : arr){
            for (int i = 0; i < 32; i++) {
                //两种表示方式
//                if ((num & (1<<i)) != 0){
//                    count[i]++;
//                }
                count[i] += (num >> i) & 1;
            }
        }
        int ans = 0;
    //两种表示方式
//        for (int i = 0; i < count.length; i++) {
//            count[i] = (count[i]%M)/K;
//        }
//        for (int i = 0; i < count.length; i++) {
//            ans |= (count[i] << i);
//        }
        for (int i = 0; i < count.length; i++) {
            if (count[i]%M !=0)
                ans |= (1 << i);
        }
        return ans;
    }

标签:map,arr,运算,rightOne,int,eor,异或,num
From: https://blog.51cto.com/u_5774355/6193526

相关文章

  • Java运算符优先级分析
    packagecom.zt.javase01;publicclassTest2{publicstaticvoidmain(String[]args){intn=10;n+=(n++)+(++n);System.out.println(n);//输出32/*(n++)(++n)从左到右执行因此(n+......
  • 存储类、运算符
    C存储类​ 存储类定义C程序中变量/函数的的存储位置、生命周期和作用域。这些说明符放置在它们所修饰的类型之前。下面列出C程序中可用的存储类:autoregisterstaticexternauto存储类auto存储类是所有局部变量默认的存储类。定义在函数中的变量默认为auto存储类,这......
  • JavaScript运算符与表达式
    目录一、===二、||三、??与?.???.四、...五、[]{}[]{}一、===严格相等运算符,用作逻辑判断1==1 //返回true1=='1' //返回true,会先将右侧的字符串转为数字,再做比较1==='1' //返回false,类型不等,直接返回falsetypeof查看某个值的类型typeof1 //返回'number'ty......
  • 为何vs编译边出来的程序ebp-4存放的不是第一个局部变量?而是security_cookie——本质上
    快速识别 最后那个call就是比较存的随机数和ebp异或的值是否和之前是否一样:    探究security_cookie在程序中的作用 from:https://www.kn0sky.com/?p=66学习环境:Windows1020H2+VisualStudio2019前言在学习看反汇编程序的时候,使用VS2019编译的releas......
  • R6-2 复数的加减运算(运算符重载)
    声明一个复数类CComplex(类私有数据成员为double型的real和image)定义构造函数,用于指定复数的实部与虚部。重载<<运算符,以格式real+imagei的格式输出当前对象(当虚部为非负数时,实部虚部中间用+号连接,当虚部为负数时,实部虚部用-号连接:如3+4i,3-4i,3+0i)。重载+运算符,实现两个复数对......
  • 逍遥自在学C语言 | 位运算符<<的高级用法
    前言在上一篇文章中,我们介绍了~运算符的高级用法,本篇文章,我们将介绍<<运算符的一些高级用法。一、人物简介第一位闪亮登场,有请今后会一直教我们C语言的老师——自在。第二位上场的是和我们一起学习的小白程序猿——逍遥。二、计算2的整数次幂代码示例#includ......
  • 数据类型和运算符
    1.整数类型TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)、BIGINT2.浮点数类型和定点数类型浮点类型:FLOAT、DOUBLE。定点类型:DECIMAL3.日期与时间类型DATETIME、DATE、TIMESTAMP、TIME、YEAR4.字符串类型CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET5.二进制类型BI......
  • 逍遥自在学C语言 | 位运算符~的高级用法
    前言在上一篇文章中,我们介绍了^运算符的高级用法,本篇文章,我们将介绍~运算符的一些高级用法。一、人物简介第一位闪亮登场,有请今后会一直教我们C语言的老师——自在。第二位上场的是和我们一起学习的小白程序猿——逍遥。二、相反数我们可以利用负数的补码性......
  • JavaScript 变量、标识符和四则运算
    JavaScript基础第二天变量什么是变量?变量由四个部分组成:1.var:声明变量的关键字2.变量名字1.变量的名字可以包含:字母,数字2.不能以数字开头3.不能使用关键字保留字比如var、if、for、列:web、_001、_number3.等于号=在js中它叫做赋值号4.值,赋值号后面的叫做值(变......
  • 表达式之运算符
    表达式必须是由值和运算符组合起来的var声明变量的关键字sum变量的名字=赋值号1+1+2表达式varsum=1+1+2;console.log(sum);varusername="你"+"好";//输出你好运算符"!"感叹号非,取反,求反"||"或,如果前面的值为true则不执行后面的,否则会执行......