• 位运算


      有关位运算(与运算,或运算,异或运算,左移和右移)是C/C++语言偏向底层的操作。市面上有很多有关位运算的算法技巧,特在此做了整理。

      1.Bitmap

      什么事Bitmap? Bitmap的核心思想就是“索引”技术,某个比特位作为key,而该比特上的值作为value(可以理解为状态位:0 or 1)。Bitmap既然利用了索引的思想,那么Bitmap这种数据结果的核心就是如何取到某个索引(即定位到某个bit)。

      实现手段上肯定是利用位运算,如果想索引到第 i 比特,可以用如下代码:

    (p + i /8) | (0x1 << (i%8)

    其中8表示一个字节的比特位数,而p + i /8,表示Bitmap所在的字节,(p + i /8) | (0x1 << (i%8) 便可以索引到当前 i bit位置。使用上面的公式,Bitmap上的两个基本操作:索引和取值:

    inline void SetBit(char* p, int pos)
    {
        p += pos / BitSize;
        *p = *p | (0x1 << (pos % BitSize));
    }
    
    inline int Getbit(char* p, int pos)
    {
        return (*(p + pos / BitSize)) | ((pos % BitSize)) ;
    }

      2.计算a与b的平均值

      如何利用位运算实现求a与b的平均值呢?先看算法:

      aveg(a, b) = (a & b) + ((a^b) >> 1) 

      a & b,则取出了a与b中相同的位,a与b相同位的平均值自然是自身。a^b取出了不同的位。而不同位的平均值则需要除以2,向左移动1位即可。

      3.不使用加减法,求a与b的和

      不使用加法而实现加法?能够想到解决的方法只能是位的运算了。考察a^b:表示了没用进位的加法,而(a&b)<<1:表示加法的进位。 a^b 与 (a&b)<<1求和,则会得到想要的结果(额,求和?递归迭代完成),代码如下:

    int sum(int a, int b)
    {
        int sum = 0;
        int carry = 0;
    
        do 
        {
            sum = a ^ b;
            carry = (a & b) << 1;
    
            a = sum;
            b = carry;
    
        } while (carry);
    
        return sum;
    }

     

  • 相关阅读:
    关于博客转移
    Leetcode 双周赛 42 题解
    Leetcode 220 周赛 题解
    Leetcode 双周赛 41 题解
    Leetcode 周赛 219 题解
    求解组成最大最小周长三角形
    友链
    维护日志
    投喂记录
    Scipy.optimization
  • 原文地址:https://www.cnblogs.com/wangbogong/p/3326052.html
Copyright © 2020-2023  润新知