bitset的一个简单实现

bitset的一个简单实现

最近有一个上亿的数据(数据较平均,重复量较小)进行排重的需求,综合考虑了各种方案,最后想到了一个简单的方案:
假设有1亿条数据需要排重,每条数据的关键字有40个字节,考虑使用hash_map,但是放入内存的话需要的内存最少为

100000000 * 40 / 1024 / 1024 / 1024 = 3.7252902984619140625 G

这是不能被接受的,因此准备采用bit_map算法,但是bit_map有可能被误删除,因此还是要保存一份数据的备份,考虑使用外存存储,虽然会牺牲一定的效率,但是可以被接受。

首先先封装了一下一个bitset的基本实现,以备后续bitmap算法操作bit位。
具体代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/type.h>
class bitset {
public:
    /** 
     * @brief 构造函数, 初始化bit数组
     * @param size      bit数组的大小
     *
     * @return
     *      void
     */
    bitset(unsigned int size):set_size(size) {
        set_data = (unsigned char *)malloc(set_size);
        memset(set_data, 0, set_size);
    }

    /** 
     * @brief 析构函数
     * @param 无
     *
     * @return 
     *     无
     */
    ~bitset() {
        if (set_data != NULL) {
            free(set_data);
            set_size = 0;
        }
    }
public:
    /** 
     * @brief 将指定位置置位为 1
     * @param pos       bit位位置
     *
     * @return
     *      void
     */
    void set(unsigned int pos) {
        unsigned char block = set_data[pos / 8];
        int index = pos % 8;
        set_data[pos / 8] |= (0x1 << index);
    }
    /** 
     * @brief 将指定位置重置为 0 
     * @param pos       bit位位置
     *
     * @return
     *      void
     */
    void reset(unsigned int pos){
        unsigned char block = set_data[pos / 8];
        int index = pos % 8;
        set_data[pos / 8] &= (( ~0 ) ^ 1 << index);
    }
    /** 
     * @brief 取指定位置的bit位的值
     * @param pos       bit位位置
     *
     * @return
     *      返回 pos 位置的bit位的值,0 / 1
     */
    unsigned int get(unsigned int pos) {
        unsigned char block = set_data[pos / 8];
        int index = pos % 8;
        return (block & (0x1 << index)) > 0 ? 1 : 0;
    }
private:
    unsigned int        set_size;           // bitset的大小
    unsigned char *     set_data;           // bitset存储的内存首地址
};

代码超级简单,只实现了三个方法:

  1. 置位方法, 该方法把指定位置的bit位置位1
    设 A 取值为 0 或1
    则有
    0 | A = A
    1 | A = 1
    因此我们只需要将我们需要重置的位设置为1,其他位置位0即可
    例如:
    将 数字AAAAAAAA的第5位置位为1
    只需要 AAAAAAAA | 00001000即可获得结果AAAA1AAA

    
    /** 
     * @brief 将指定位置置位为 1
     * @param pos       bit位位置
     *
     * @return
     *      void
     */
    void set(unsigned int pos) {
        unsigned char block = set_data[pos / 8];
        int index = pos % 8;
        set_data[pos / 8] |= (0x1 << index);
    }
  2. 重置方法 该方法把指定bit位重置为0,原理为:
    设 A 取值为 0 或1
    则有
    0 & A = 0
    1 & A = A
    因此我们只需要将我们需要重置的位设置为0,其他位置位1即可
    例如:
    将 数字AAAAAAAA的第5位置位为0
    只需要 AAAAAAAA & 11110111即可获得结果AAAA0AAA

     /** 
     * @brief 将指定位置重置为 0 
     * @param pos       bit位位置
     *
     * @return
     *      void
     */
    void reset(unsigned int pos){
        unsigned char block = set_data[pos / 8];
        int index = pos % 8;
        set_data[pos / 8] &= (( ~0 ) ^ 1 << index);
  1. 取bit位的值的方法
    原理为:
    设 A 取值为 0 或1
    则有
    0 & A = 0
    1 & A = A
    因此我们只需要将我们需要取的bit位设置为1,其他位置位0即可
    例如:
    将 数字AAAAAAAA的第5位置位为1
    只需要 AAAAAAAA & 00001000即可获得结果0000A0000
    若 A 为 0 则结果为0, 否则大于0
     /** 
     * @brief 取指定位置的bit位的值
     * @param pos       bit位位置
     *
     * @return
     *      返回 pos 位置的bit位的值,0 / 1
     */
    unsigned int get(unsigned int pos) {
        unsigned char block = set_data[pos / 8];
        int index = pos % 8;
        return (block & (0x1 << index)) > 0 ? 1 : 0;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值