位运算(3)-- 高级运用

注:此文内容来自于对【数据结构与算法之位运算】课程所做的笔记

一、二进制中1的个数

问题:给定一个无符号整型变量,求其二进制表示中“1”的个数。
相似问题:判断整数A转换成整数B需要的次数。(A ^ B,再求“1”的个数)
分析:很容易想到右移,然后判断奇偶性,复杂度与最左侧的1的位置相关。

int oneCount(unsigned int n){
    int c = 0;
    while(n){
        c += n & 1;
        n >>= 1;
    }
    return c;
}

优化1.:利用判断一个整数是否是2的幂采用的方法,每一次判断都会找到一个1,直到整数变为0为止。复杂度与1的个数相关。

int oneCount1(unsigned int n){
    int c = 0;
    while(n){
        n &= (n - 1);   // 清除最低位的1
        c++;
    }
    return c;
}

优化2.:采用并行化规约思想进行优化。在GPU编程中,为了加速求和操作,会采用并行化规约技术使多个线程参与计算,从而将复杂度由O(n)将为O(logn). 位运算可以看成不同 bit 之间的线程并行。

int oneCount2(unsigned int n){

         /*获得偶数位的值*/   /*获得奇数位的值*/        // 常数的二进制表示
    n = (n & 0x55555555) + ((n >> 1)  & 0x55555555);    // 0101010101010101...
    n = (n & 0x33333333) + ((n >> 2)  & 0x33333333);    // 0011001100110011...
    n = (n & 0x0f0f0f0f) + ((n >> 4)  & 0x0f0f0f0f);    // 0000111100001111...
    n = (n & 0x00ff00ff) + ((n >> 8)  & 0x00ff00ff);    // 0000000011111111...
    n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff);    // 0000000000000000...

    return n;
}

优化3.:编译器内置位运算,GCC下是__builtin_popcount,VS下是__popcnt

int oneCount3(unsigned int n){
    return __builtin_popcount(n);   // VS: __popcnt(n)
}

二、最左侧1问题

问题:给定一个整数,判断该整数最左侧1的位置 (most significant bit or count leading zeros problem)
way 1.:通过逐次移位获得最高位(左移右移皆可),复杂度较高。

int left_most_one_1(int n){
    int pos = -1;
    while(n){
        n >>= 1;
        pos++;
    }
    return pos;
}

way 2.:通过二分法寻找最左侧1,复杂度较way1降低很多。

int left_most_one_2(int n){
    if(n == 0) return -1;

    int exp = 4;
    int pos = (1 << exp);   //16的位置开始二分
    while(exp > 0){
        exp--;
        if(n >> pos) pos += (1 << exp);
        else pos -= (1 << exp);
    }
    ret
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值