zoukankan      html  css  js  c++  java
  • C++ 二维 Bit Map

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    using namespace std;
    
    class BitArray2D
    {
    private:
        int mRow, mCol;
        unsigned char **A, *B;
        bool isValid(int row, int col)
        {
            return row > 0 && col > 0 && row <= mRow && col <= mCol;
        }
        
    public:
        BitArray2D(const int &row, const int &col) : mRow(row), mCol(col)
        {
            if(!isValid(row, col))
                std::cerr << "parameter error." << std::endl;
    
            int i, j;
            int r = row;
            int c = (col%8 == 0) ? col/8 : col/8 + 1;
            
            A = new unsigned char *[r]();
            B = new unsigned char[r*c]();
    
            for(i=0,j=0; i < r; i++)
            {
                A[i] = &B[j];
                j += c;
            }
        }
    
        ~BitArray2D()
        {
            delete B;
            delete []A;
        }
    
        bool bitGet(int row, int col)
        {
            if(!isValid(row, col))
                return false;
            return A[row][col >> 1] & (1 << col);
        }
        
        void setOne(int row, int col)
        {
            if(!isValid(row, col))
                return;
            A[row][col >> 1] |= (1 << col);
        }
    
        void setZero(int row, int col)
        {
            if(!isValid(row, col))
                return;
            A[row][col >> 1] &= ~(1 << col);
        }
    };
    
    
    int main()
    {
        BitArray2D ba(3,4);
        ba.setOne(1,2);
        int i,j;
        for(i = 0; i < 3; i++)
        {
            for(j = 0; j < 4; j++)
            {
                std::cout << ba.bitGet(i,j) << " ";
            }
            std::cout << std::endl;
        }
        std::cout << ba.bitGet(1,2) << std::endl;
    }

     想尽各种办法实现[][]的重载都失败了。只好用()替代。使用起来也还行。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /*
     *  1. clear
     *  2. setOne/Zero
     *  3. get
    */
    #define SHIFT 5  // 32 = 2^5
    #define MASK  0x1f        // 0001 1111    5bits [0,31]
    void bitSetOne(int *A, int idx)
    {
        int *pA = A;
        // idx>>5即idx/32      1 left shift [0,31]
        // p[0] = p[0] | 000001000                              idx & MASK即截取idx有效的范围(0~2^5),实际上改成判断更合适,最后取或运算设置进去。相当于取模的运算
        pA[idx >> 5] |= (1 << (idx & MASK));                    // 1左移这么多位,设置进去。在内存中,实际上的存储顺序还是从每个int的低位到高位,只不过读取的过程中经过了计算,对外就像是连续的
    }
    void bitSetZero(int *A, int idx)
    {
        int *pA = A;
        pA[idx >> 5] &= ~(1 << (idx & MASK));
    }
    
    int bitGet(int *A, int idx)
    {
        int *pA = A;
        return pA[idx >> 5] & (1 << (idx & MASK));
    }
    
    #include <stdlib.h>
    
    int main()
    {
        const int N = 100;     // 100 bits
        
        int A[1+N/32];         // size = 4  32 bits
        memset(A, 0, sizeof(A));
        bitSetOne(A, 1);
        bitSetOne(A, 3); 
        printf("%d
    ", A[0]);
    
        if(bitGet(A, 0)) printf("1"); else printf("0"); 
        if(bitGet(A, 1)) printf("1"); else printf("0"); 
        if(bitGet(A, 2)) printf("1"); else printf("0"); 
        if(bitGet(A, 3)) printf("1"); else printf("0"); puts("");
    
        bitSetZero(A, 1);
        if(bitGet(A, 1)) printf("1"); else printf("0"); puts("");
    }

     注意

    1 逻辑右移和算术右移
    
    逻辑右移,移走的位填充为0;算术右移,移走的位填充与符号位有关,例如如果为负数,则移走的位填充为1。
    
    2 unsigned int 和 int
    
    C语言的标准指出,无符号数执行的所有移位操作都是逻辑的,而对于有符号数,采用哪种方式取决于编译器。算术左移和逻辑左移是相同的,而算术右移和逻辑右移,取决于符号位。因此,一个程序如果使用了有符号数,是不可移植的。嵌入式的程序通常采用交叉编译开发,如果定义为有符号的,就无法保证右移操作能跨平台使用,这就是为什么用unsigned int,而不用int的主要原因。
  • 相关阅读:
    vue vmodel input type=checkbox的问题
    springboot配置文件优先级
    原生js实现复制功能
    Long.valueOf和Long.parseLong的区别
    程序员学习参考
    国外开源项目
    .NET快速入门教程
    Microsoft Update Catalog 离线安装包下载
    php header示例代码
    CentOS下iptables设置
  • 原文地址:https://www.cnblogs.com/abnk/p/12780507.html
Copyright © 2011-2022 走看看