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++中位运算操作符的使用

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

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

c++中的位运算计算问题

Python全栈之路——第2话