C語言,開篇-位運算


位運算有很大的妙用,在C語言中發揚光大。有什麼做用呢?在數據結構和算法中有個很重要的概念就是:時間和空間。位運算就能夠提升時間的效率和空間的利用率。算法


1、位運算增長空間的利用率。

      沒有什麼神奇之處,只是以緊湊的二進制格式來描述數據結構,應用之多舉不勝舉。記住,最小的存儲單元是bit而不是byte數據結構


2、位運算提升時間的效率。

      根本緣由是讀取內存次數少,咱們知道CPU一次讀取內存的最大字節數和字長有關,正是由於把數據壓縮在有限的數據結構中,讀取內存的次數大大減小。數據結構和算法


應用舉例:

    一、如何不使用中間變量,交換兩個變量? ide


a = a ^ b;
b = a ^ b;
a = a ^ b;

    可能會有人說使用加減法也能夠,如:測試

a = a + b;
b = a - b;
a = a - b;

    可是加減法是有反作用的,容易致使數據溢出。spa


二、狀態的改變,咱們可能常常寫相似下面的代碼:內存


if (b) {
     b = false;
} else {
     b = true;
}

      或者更精簡一點get

b = b ? false : true;

      但依然會彆扭,由於你要改變一個標誌的狀態,首先要知道原有狀態,使用位運算能夠避免it

b ^= b;


三、位向量,不少底層庫中都有位向量的類,可用於不少場合,高效環保。我本身寫了一個位向量,求解1億一下素數,時間不到3秒,內存佔用不到13M,可見位運算的威力。io


#define LONG_BIT_LENGTH sizeof(long)
#define BIT_SHIFT_UNIT (LONG_BIT_LENGTH/8 + 1)
#define BIT_MASK (LONG_BIT_LENGTH-1)
//位向量結構:方便同時使用多個位向量
typedef struct tag_bit_vector {
    long *bit_buffer;       //數據區
    long max_bit_num;       //總bit數
}TBitVector;
//========================================================================================
//分配一個位向量
TBitVector *mallc_bit_vector(long bit_max) {
    TBitVector *pbit_vector = 0;
    pbit_vector = (TBitVector *)malloc(sizeof(TBitVector));
    if (pbit_vector == NULL) return NULL;
    pbit_vector->bit_buffer = (long *)calloc(LONG_BIT_LENGTH, (bit_max + BIT_MASK) >> BIT_SHIFT_UNIT);
    if (pbit_vector->bit_buffer == NULL) return NULL;
    pbit_vector->max_bit_num = bit_max;
    return pbit_vector;
}
//釋放一個位向量
void free_bit_vector(TBitVector *bit_vector) {
    free(bit_vector->bit_buffer);
    free(bit_vector);
}
//========================================================================================
//設置
void set_bit_vector(TBitVector *bit_vector, long idx) {
    if (idx >= bit_vector->max_bit_num) return;
    bit_vector->bit_buffer[idx >> BIT_SHIFT_UNIT] |= 1 << (idx & BIT_MASK);
}
//清除
void cls_bit_vector(TBitVector *bit_vector, long idx) {
    if (idx >= bit_vector->max_bit_num) return;
    bit_vector->bit_buffer[idx >> BIT_SHIFT_UNIT] &= ~(1 << (idx & BIT_MASK));
}
//探測
int test_bit(TBitVector *bit_vector, long idx) {
    if (idx >= bit_vector->max_bit_num) return 0;
    return bit_vector->bit_buffer[idx >> BIT_SHIFT_UNIT] & (1 << (idx & BIT_MASK));
}


   求解素數代碼:

int sievePrime(TBitVector *pBitVerctor, unsigned long prime)
{
    unsigned long i;
    if (prime*prime >= pBitVerctor->max_bit_num)
    {
        return 0;
    }
    for (i=prime<<1; i<pBitVerctor->max_bit_num; i+=prime)
    {
        set_bit_vector(pBitVerctor, i);
    }
    return -1;
}
//測試
#define PRIME_NUMBER_MAX 100000000
int main(int argc, char *argv[])
{
    int milisection = 0;
    int i = 0;
    int primeCount = 0;
    struct timeval start;
    struct timeval end;
    TBitVector *pdata = mallc_bit_vector(PRIME_NUMBER_MAX);
    milisection = GetTickCount(&start);
    for (i=2; i<PRIME_NUMBER_MAX; i++)
    {
        if (test_bit(pdata, i))
            continue;
        if (sievePrime(pdata, i) == 0)
        {
            break;
        }
    }
                                                                  
    GetTickCount(&end);
    printf("times : %d\n", (end.tv_sec * 1000 * 1000 + end.tv_usec) - (start.tv_sec * 1000 * 1000 + start.tv_usec));
    free_bit_vector(pdata);
    getchar();
    return 0;
}


總結: 位運算應用場景還有不少,要想用好,主要看你的抽象能力。如今是大內存和多核時代,沒有必要時也不建議使用,除非用在密集運算或須要高效率的算法上。

相關文章
相關標籤/搜索