C/C++中位运算在实际中的应用

Posted 小丑快学习

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++中位运算在实际中的应用相关的知识,希望对你有一定的参考价值。

位运算在C/C++语言中经常用到,记录一下位运算在实际中常用的类型。

用作bool数组

了解位图之前应该先了解位运算的基本操作的组合;

  • 清零特定位 (mask中特定位置0,其它位为1,s=s&mask)
  • 取某数中指定位 (mask中特定位置1,其它位为0,s=s&mask)
  • 常用来将源操作数某些位置1,其它位不变。 (mask中特定位置1,其它位为0 s=s|mask)
  • 使特定位的值取反 (mask中特定位置1,其它位为0 s=s^mask)
  • 取反操作 ~
  • 设置相应的位
     1.计算下标 i
     2.将相应的位设置为 1 
         代码:
         unsigned int mask = 1;
         mask = mask << i;
         flag = flag | mask;

         简洁写法:
         flag |= (0x1 << i);(从右到左计数 31 <- 0) 
         flag |= (0x80000000 >> i);(从左到右 0 -> 31)
  • 清除相应的位
     1.计算下标 i
     2.将相应的位设置位 0
         代码:
         unsigned int mask = 1;
         mask = mask << i;
         mask = ~mask;
         flag = flag & mask;
         简介写法:
         flag &= ~(0x1 << i)(从右到左)
         flag &= ~(0x80000000 >> i);(从左到右)

  • 获取相应的位,即判断某位的值为 1 还是 0;
       1. 计算需要判定的索引为 i;
       2. 判断 flag & (1 << i)(右到左) 的值,左到右则位 flag & (0x80000000 >> i)
           为 0 :则索引 i 对应的位为 0;
           非 0: 则索引 i 对应的位为 1;
           例子:
           //第 10 位为 0
           if((a & (1 << 10)) == 0){
               cout << " 第十位为 0 " << endl;
           }
           //第 31 为 1
           if((a & (1 << 31)) != 0){
               cout << " 第 31 位为 1 " << endl;
           }

i)代替布尔类型的数组
按位与操作最常用的就是用整数来代替 vector<bool>类型的数组,如下的代码:

#include <iostream>  
#include<vector>
#include<string>

#include <stdio.h>
#include <string.h>

using namespace std;
extern int errno ;

//封装一个bool类型的数组,采用位图来存储信息
class vector_bool{
public:
    vector_bool(unsigned int size, bool init = false)
    :size_(size), init_(init)
    {
        arr = (unsigned int*)malloc(sizeof(unsigned int)*(size_/32 + 1));
        if(!arr){
            perror("内存分配异常!");
        }
        unsigned int init_val = init_ ? full_true : full_false;
        for(int i = 0; i <= (size_ / 32 + 1); i++){
            arr[i] = init_val;
        }
    }
    ~vector_bool(){
        if(arr){
            free(arr);
        }
    }
    //将特定索引 index 的值设置位 val
    void set_val_of(int index, bool val){
        unsigned int arr_index = index / 32;
        unsigned int bit_index = index % 32;
        if(index < size_ && index >=0){
            if(val == true){
                arr[arr_index] |= (mask >> bit_index);
            }else{
                arr[arr_index] &= ~(mask >> bit_index);
            }
        }else{
            fprintf(stderr, "索引越界!\\n");
            exit(-1);
        }
    }
    //获取相应的位的值
    bool get_val_of(int index){
        if(index < size_ && index >=0){
            return (arr[index / 32] & (mask >> (index % 32))) == 0 ? false : true;
        }else{
            fprintf(stderr, "索引越界!\\n");
            exit(-1);
        }
    }

    void print(){
       for(int i = 0 ;i < (size_/32 + 1) ; i++){
           Binary(i);
       }
       cout << endl;
    }
private:
    unsigned int size_;//数组的大小
    bool init_;//数组的初始状态
    unsigned int *arr;
    enum{
        full_true = 0xffffffff,
        full_false = 0x0,
        mask = 0x80000000
    };
	//将一个整数打印为二进制形式
    void Binary(unsigned int n)  
    {
        int count[32] = {0};
        int index = 31;
        while (n != 0)
        {
            count[index--] = n%2;
            n = n /2 ;
        }
        for(int i = 0; i < 32; ++i){
           cout<<count[i];
        }
    }
};

以上是关于C/C++中位运算在实际中的应用的主要内容,如果未能解决你的问题,请参考以下文章

C/C++中位运算杂谈

C/C++中位运算操作符的使用

latex在vim中的代码片段

C/C++ 三元运算符实际上是不是具有与赋值运算符相同的优先级?

环形链表(哈希表链表)寻找两个正序数组的中位数(数组二分查找)二进制求和(位运算数学)

Ruby 代码中的 C/C++?