哈希扩展学习

哈希扩展学习

位图

位图本质是⼀个直接定址法的哈希表,每个整型值映射⼀个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;
 }
 }
 }
相关推荐
05Kevin7 小时前
lk每日冒险题--数据结构6.27
算法
To_OC17 小时前
从一次栈溢出报错说起,我把递归彻底扒明白了
javascript·算法·程序员
千纸鹤安安1 天前
千问Qwen-AgentWorld来了:一个语言模型搞定七大Agent场景,GPT-5.4都输了
算法
七牛开发者1 天前
MCP 到底是什么?为什么 Agent 都想接上它
算法·aigc·agent
kisshyshy1 天前
从递归到迭代,一文吃透二叉树的核心知识与 JavaScript 实现
javascript·算法·代码规范
To_OC2 天前
LC 49 字母异位词分组:想到哈希表很简单,选对 key 才是精髓
javascript·算法·leetcode
用户938515635072 天前
从 O(n²) 到 O(nlogn):一文读懂快速排序的“快”与“妙”
javascript·算法