1. 程式人生 > 其它 >MySQL 索引使用案例

MySQL 索引使用案例

目錄

位移運算

  • <<運算

    • a<<b 表示把a轉為二進位制後左移b位(在後面新增 b個0)。例如100的二進位制表示為1100100,100左移2位後(後面加2個零):1100100<<2 =110010000 =400,可以看出,a<<b的值實際上就是a乘以2的b次方,因為在二進位制數後面新增一個0就相當該數乘以2,2個零即2的2次方 等於4。通常認為a<<1比a*2更快,因為前者是更底層一些的操作。因此程式中乘以2的操作儘量用左移一位來代替。

    • 定義一些常量可能會用到<<運算。你可以方便的用1<<16 -1 來表示65535(unsingned int 最大值16位系統)。很多演算法和資料結構要求資料模組必須是2的冪,此時就可以用<<來定義MAX_N等常量。

  • >>運算

    • 和<<相似,a>>b表示二進位制右移b位(去掉末b位),相當於a除以2的b次方(取整)。我們經常用>>1來代替 /2(div 2),比如二分查詢、堆的插入操作等等。想辦法用>>代替除法運算可以使程式的效率大大提高。最大公約數的二進位制演算法用除以2操作來代替慢的出奇的%(mod)運算,效率可以提高60%。
  • n & 1 就是取最左邊位

  • n >>= 1(n = n>>1)就是將n右移一位

數學運算轉化為位運算:

  • 向下整除 n//2 (C++中就是n/2)等價於右移一位 n >> 1;

  • 取餘數n%2 等價於判斷二進位制最右位 n & 1;

JS15 二進位制中 1 的個數(位移運算)

class Solution {
public:
    int hammingWeight(uint32_t n) {
        unsigned int res =0; // c++ 使用無符號數
        while(n!=0){
            res += n & 1;
            n >>= 1;  // 將二進位制數字 n 無符號右移一位
        }
        return res; 
        
    }
};

JS16 數值的整數次方:實現pow(x,n)(位移運算)

class Solution {
public:
    double myPow(double x, int n) {
        if(x == 0.0f) return 0.0;
        long b = n;  // 將n存入long變數,int32 變數區間n∈[−2147483648,2147483647] ,因此當n=−2147483648 時執行n=−n 會因越界而賦值出錯。解決方法是先將 n 存入 long 變數 b,後面用 b 操作即可
        double result = 1.0;
        // 當 冪次為負時
        if(b < 0){
            x = 1/x;
            b = -b;
        }
        // 
        while(b > 0){
            if((b&1) == 1) result*=x;
            x *= x;
            b >>= 1;
        }
        return result;
    }
};

JS56 陣列中數字出現的次數I(異或運算)

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        int x=0, y=0; // 記錄只出現一次的兩個數字
        int n =0;  // 記錄異或結果
        int m =1;  // 為了獲取x和y異或結果中第一個1出現的位置,即從右到左 x和y第一個不同的位置
        // 1.遍歷nums進行異或,實際最後結果是x和y的異或結果
        for(int num:nums){
            n ^=num;
        }
        // 2.迴圈左移計算m即x和y異或結果中第一個1出現的位置
        while((n & m) == 0){
            m <<= 1;
        }
        // 4、通過m拆分nums為兩個子陣列,並進行異或
        for(int num:nums){
            if(num & m) x^= num;  // 當num&m!=0
            else y^=num; // 當num&m==0
        }
        // 5. 返回出現一次的數字
        return vector<int> {x,y};
    }
};

陣列中數字出現的次數II(異或運算)

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ones=0, twos =0;
        for(int num:nums){
            ones = ones ^ num & ~twos;
            twos = twos ^ num & ~ones;
        }
        return ones;
    }
};

JS65 不用加減乘除做加法

class Solution {
public:
    int add(int a, int b) {
        while(b !=0){
            int c = (unsigned int)(a & b) << 1;
            a ^= b;
            b = c;
        }
        return a;
    }
};