位运算相关总结

计算机CPU中ALU是由逻辑门构成的,非常善于位运算。因此,在程序中使用位运算,经常能够加快程序运行。另外,掌握一些位运算的相关知识也能增加一些编程的乐趣。

位运算经常使用到异或运算和与运算。异或运算符合交换律、结合律,它的特点是相同为0,不同为1。与运算是同为1则为1。

在这里举几个跟位运算相关的例子:
1、**两个数比较大小
2、数组中出现奇数次的数
3、找出数组中两个出现奇数次的数
4、交换两个变量的值

详细内容
1、两个数比较大小
描述:给定两个整数a和b,用位运算比较两个数的大小,并将较大的数返回。
分析:首先计算a和b的差值c。通过判断c的符号来得到它们中较大的值。
示例代码

public int sig(int c) {
    return ((c >>> 31) & 1) == 0 ? 1 : 0;
}
public int nsig(int c) {
    return sig(c) == 0 ? 1 : 0;
}
public int getMax1(int a, int b) {
    int c = a - b;
    int sigc = sig(c);
    int nsigc = nsig(c);
    return a * sigc + nsigc * b;
}

总结:直接相减可能会出现越界的问题,如何处理?

2、数组中出现奇数次的数
描述:一个整数数组中有一个数出现了奇数次,实现一个O(n)复杂度的算法找到这个值。
分析:利用异或运算相同则为零的性质,来找到数组中出现奇数次的值。
示例代码

public int findOdd(int[] A, int n) {
    if (A == null || A.length < n) {
        return -1;
    }
    int ret = 0;
    for (int i = 0; i < n; i++) {
        ret = ret ^ A[i];
    }
    return ret;
}

总结:待整理

3、找出数组中两个出现奇数次的数
描述:一个整数数组中有两个数出现了奇数次,实现一个O(n)复杂度的算法找到这两个值。返回这两个值,并且较小的值在前。
分析:首先遍历这个数组,可以得到这两个数的异或值e。设e的二进制形式最右侧1的位置表示的数为k。因为e中logk位置为1,那么这两个数中必有一个数的二进制形式在logk位置是1。有了这个性质,再遍历这个数组,e0只和数组中二进制形式logk位置为1的数做异或操作,那么e0就是出现奇数次的数。然后e异或e0的结果就是另一个出现奇数次的整数。
示例代码

public int[] findOdds2(int[] arr, int n) {
    int e = 0, e0 = 0;
    for (int curNum : arr)  { e ^= curNum;  }
    int rightOne = e & (~e + 1);//快速求得右侧第一个1出现的位置
    for (int cur : arr) {
        if ((cur & rightOne) != 0) {
            e0 ^= cur;
        }
    }
    int small = Math.min(e0, (e ^ e0));
    int big = Math.max(eOhasOne, (eO ^ eOhasOne));
    return new int[] { small, big };
}

总结:待整理

4、交换两个变量的值
描述:请编写一个算法,不用任何额外变量交换两个整数的值。 给定一个数组num,其中包含两个值,请不用任何额外变量交换这两个值,并将交换后的数组返回。
分析
a’=a^b;
b’=a’^b=a^b^b=a;
a’=a’^b’=a^b^a^b^b=b;
示例代码

public int[] getSwap(int[] num) {
    if (num == null || num.length < 2) { return null; }
    num[0] = num[0] ^ num[1];
    num[1] = num[0] ^ num[1];
    num[0] = num[0] ^ num[1];
    return num;
}

总结:待整理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值