哈希扩展学习

哈希扩展学习

位图

位图本质是⼀个直接定址法的哈希表,每个整型值映射⼀个bit位,位图提供控制这个bit的相关接⼝。

实现中需要注意的是,C/C++没有对应位的类型,只能看int/char这样整形类型,我们再通过位运算去 控制对应的⽐特位。⽐如我们数据存到vector中,相当于每个int值映射对应的32个值,⽐如第⼀ 个整形映射0-31对应的位,第⼆个整形映射32-63对应的位,后⾯的以此类推,那么来了⼀个整形值 x,i=x/32;j=x%32;计算出x映射的值在vector的第i个整形数据的第j位。

解决给40亿个不重复的⽆符号整数,查找⼀个数据的问题,我们要给位图开2^32个位,注意不能开40 亿个位,因为映射是按⼤⼩映射的,我们要按数据⼤⼩范围开空间,范围是是0-2^32-1,所以需要开 2^32个位。然后从⽂件中依次读取每个set到位图中,然后就可以快速判断⼀个值是否在这40亿个数中 了。

代码如下:

C++ 复制代码
namespace bit
 {
    // N
是需要多少⽐特位    template<size_t N>
    class bitset
    {
    public:
            bitset()
            {
                    //_bits.resize(N/32+1, 0);
                    _bits.resize((N >> 5) + 1, 0);
            }
            
            // 
把
x
映射的位标记成
1
            void set(size_t x)
            {
                    size_t i = x / 32;
                    size_t j = x % 32;
                    _bits[i] |= (1 << j);
            }
            
            // 
把
x
映射的位标记成
0
            void reset(size_t x)
            {
                    size_t i = x / 32;
                    size_t j = x % 32;
                    _bits[i] &= ~(1 << j);
            }
            bool test(size_t x)
            {
                    size_t i = x / 32;
                    size_t j = x % 32;
                    return _bits[i] & (1 << j);
            }
    private:
            vector<int> _bits;
    };
 }

位图的优缺点

优点:增删查改快,节省空间 缺点:只适⽤于整形

C++ 复制代码
// 
模拟位图找交集void test_bitset1()
 {
        int a1[] = { 5,7,9,2,5,99,5,5,7,5,3,9,2,55,1,5,6 };
        int a2[] = { 5,3,5,99,6,99,33,66};
        bitset<100> bs1;
        bitset<100> bs2;
        for (auto e : a1)
        {
                bs1.set(e);
        }
        for (auto e : a2)
        {
                bs2.set(e);
        }
        for (size_t i = 0; i < 100; i++)
        {
                if (bs1.test(i) && bs2.test(i))
                {
                        cout << i << endl;
                }
        }
 }
        
template<size_t N>
 class twobitset
 {
 public:
        void set(size_t x)
        {
                bool bit1 = _bs1.test(x);
                bool bit2 = _bs2.test(x);
                if (!bit1 && !bit2) // 00->01
                {
                        _bs2.set(x);
                }
                else if (!bit1 && bit2) // 01->10
                     {
                        _bs1.set(x);
                        _bs2.reset(x);
                }
                else if (bit1 && !bit2) // 10->11
                {
                        _bs1.set(x);
                        _bs2.set(x);
                }
        }
        // 
返回
0 
出现
0
次数        // 
返回
1 
出现
1
次数        // 
返回
2 
出现
2
次数        // 
返回
3 
出现
2
次及以上        int get_count(size_t x)
        {
                bool bit1 = _bs1.test(x);
                bool bit2 = _bs2.test(x);
                if (!bit1 && !bit2)
                {
                        return 0;
                }
                else if (!bit1 && bit2)
                {
                        return 1;
                }
                else if (bit1 && !bit2)
                {
                        return 2;
                }
                else
                {
                        return 3;
                }
        }
 private:
        bitset<N> _bs1;
        bitset<N> _bs2;
 };
 };
 void test_bitset2()
 {
        bit::twobitset<100> tbs;
     int a[] = { 5,7,9,2,5,99,5,5,7,5,3,9,2,55,1,5,6,6,6,6,7,9 };
 for (auto e : a)
 {
 tbs.set(e);
 }
 for (size_t i = 0; i < 100; ++i)
 {
 //cout << i << "->" << tbs.get_count(i) << endl;
 if (tbs.get_count(i) == 1 || tbs.get_count(i) == 2)
 {
 cout << i << endl;
 }
 }
 }
相关推荐
hd51cc2 小时前
MFC消息 学习笔记
笔记·学习·mfc
Dev7z3 小时前
基于MATLAB数学形态学的边缘检测算法仿真实现
算法·计算机视觉·matlab
盐焗西兰花8 小时前
鸿蒙学习实战之路:状态管理最佳实践
学习·华为·harmonyos
风筝在晴天搁浅9 小时前
代码随想录 718.最长重复子数组
算法
kyle~9 小时前
算法---回溯算法
算法
小毅&Nora9 小时前
【人工智能】【深度学习】 ⑦ 从零开始AI学习路径:从Python到大模型的实战指南
人工智能·深度学习·学习
Maxwell_li19 小时前
Pandas 描述分析和分组分析学习文档
学习·数据分析·numpy·pandas·matplotlib
star _chen9 小时前
C++实现完美洗牌算法
开发语言·c++·算法
雷工笔记9 小时前
MES学习笔记之SCADA采集的数据如何与MES中的任务关联起来?
笔记·学习
hzxxxxxxx10 小时前
1234567
算法