【C++ 学习 ㉖】- 位图详解(哈希扩展)

news2024/11/28 0:45:28

目录

一、位图的概念

二、位图的实现

2.1 - bitset.h

2.2 - test.cpp

三、位图的应用

3.1 - 例题一

3.2 - 例题二


 


一、位图的概念

假设有这样一个需求:在 100 亿个整型数字中快速查询某个数是否存在其中,并假设是 32 位操作系统,4 GB 内存。

由于数字的数量如此之多,如果使用一个 int 型的数组进行存储,需要占用的内存空间为 \dfrac{4 \times 10^{10}}{1024 \times 1024 \times 1024} \approx 37.25 GB,那么如何用更小的空间来 "存储" 这些数字呢?

我们可以用比特位(bit)来标记数字,每个比特位中存放的值则表示其标记的数字是否存在,0 表示不存在,1 表示存在,这就是位图的基本思想

例如,标记数字 1、2、4、6:

由于 int 总共有 2^{32} 种取值,所以标记所有这些数字需要占用的内存空间为 \dfrac{2^{32}}{8 \times 1024 \times 1024 \times 1024} = 0.5GB


二、位图的实现

2.1 - bitset.h

#pragma once
​
#include <vector>
​
namespace yzz
{
    template<size_t N>  // 总共有 N + 1 个比特位
    class bitset
    {
    public:
        bitset() : _v(N / 32 + 1) { }
​
        void set(size_t x)
        {
            size_t i = x / 32;
            size_t j = x % 32;
            _v[i] |= (1 << j);
        }
​
        void reset(size_t x)
        {
            size_t i = x / 32;
            size_t j = x % 32;
            _v[i] &= ~(1 << j);
        }
​
        bool test(size_t x) const
        {
            size_t i = x / 32;
            size_t j = x % 32;
            return _v[i] & (1 << j);
        }
    private:
        std::vector<int> _v;
    };
}

2.2 - test.cpp

#include "bitset.h"
#include <iostream>
using namespace std;
​
int main()
{
    int arr[] = { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 };
    yzz::bitset<0xffffffff> bs;
    for (const int& e : arr)
    {
        bs.set(e);
    }
    bs.reset(-3);
    bs.reset(3);
    for (const int& e : arr)
    {
        if (bs.test(e))
            cout << e << " ";
    }
    // -5 -4 -2 -1 0 1 2 4 5
    cout << endl;
    return 0;
}


三、位图的应用

位图的应用是大量数据的快速排序、查找和去重

3.1 - 例题一

给定 100 亿个整数,找到只出现一次的所有整数

doublebitset.h

#pragma once
​
#include "bitset.h"
​
namespace yzz
{
    template<size_t N>
    class doublebitset
    {
    public:
        void set(size_t x)
        {
            if (_bs1.test(x) == 0 && _bs2.test(x) == 0)  // 00 -> 01
            {
                _bs2.set(x);
            }
            else if (_bs1.test(x) == 0 && _bs2.test(x) == 1)  // 01 -> 10
            {
                _bs1.set(x);
                _bs2.reset(x);
            }
            // 10 则不变
        }
​
        bool isSingleNum(size_t x) const
        {
            return _bs1.test(x) == 0 && _bs2.test(x) == 1;
        }
    private:
        bitset<N> _bs1;
        bitset<N> _bs2;
    };
}
  1. 思路:用 2 个比特位来表示一个数字的状态,00 表示不存在,01 表示只出现一次,10 表示出现一次以上。

    具体实现则是使用两个位图

  2. 思考:给定 100 亿个整数,找到出现次数不超过 2 次的所有整数

    思路是类似的,用 2 个比特位来表示一个数字的状态,00 表示不存在,01 表示只出现一次,10 表示出现两次,11 表示出现两次以上

test.cpp

#include "doublebitset.h"
#include <iostream>
using namespace std;
​
int main()
{
    int arr[] = { -3, -3, -2, -1, -2, 0, 1, 1, 2, 2, 3 };
    yzz::doublebitset<0xffffffff> dbs;
    for (const int& e : arr)
    {
        dbs.set(e);
    }
    for (const int& e : arr)
    {
        if (dbs.isSingleNum(e))
            cout << e << " ";
    }
    // -1 0 3
    cout << endl;
    return 0;
}

3.2 - 例题二

给两个文件,分别有 100 亿个整数,求两个文件的交集

法一

#include "bitset.h"
#include <iostream>
using namespace std;
​
int main()
{
    int arr1[] = { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 };
    int arr2[] = { -3, -3, -2, -1, -2, 0, 1, 1, 2, 2, 3 };
    yzz::bitset<0xffffffff> bs1;
    yzz::bitset<0xffffffff> bs2;
    // 去重
    for (const int& e : arr1)
    {
        bs1.set(e);
    }
    for (const int& e : arr2)
    {
        bs2.set(e);
    }
    // 求交集
    for (int i = -10; i <= 10; ++i)
    {
        if (bs1.test(i) && bs2.test(i))
            cout << i << " ";
    }
    // -3 -2 -1 0 1 2 3
    cout << endl;
    return 0;
}

法二

#include "bitset.h"
#include <iostream>
using namespace std;
​
int main()
{
    int arr1[] = { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 };
    int arr2[] = { -3, -3, -2, -1, -2, 0, 1, 1, 2, 2, 3 };
    yzz::bitset<0xffffffff> bs;
    for (const int& e : arr1)
    {
        bs.set(e);
    }
    for (const int& e : arr2)
    {
        if (bs.test(e))
        {
            cout << e << " ";
            bs.reset(e);  // 避免出现重复的数字
        }
    }
    // -3 -2 -1 0 1 2 3
    cout << endl;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1070132.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是零日攻击?

零日攻击 1. 什么是零日漏洞2. 什么是零日市场3. 如何将零日漏洞转化为零日攻击4. 零日攻击的主要目标5. 典型零日攻击事件 1. 什么是零日漏洞 零日攻击是指利用零日漏洞对系统或软件应用发动的网络攻击。 零日漏洞也称零时差漏洞&#xff0c;通常是指还没有补丁的安全漏洞。…

代码随想录算法训练营第四十五天 | 1049. 最后一块石头的重量 II、494. 目标和、474.一和零

1049. 最后一块石头的重量 II 视频讲解&#xff1a;动态规划之背包问题&#xff0c;这个背包最多能装多少&#xff1f;LeetCode&#xff1a;1049.最后一块石头的重量II_哔哩哔哩_bilibili 代码随想录 &#xff08;1&#xff09;代码 494. 目标和 视频讲解&#xff1a;动态规划…

10.8号作业

LED三盏灯的交替闪烁 .text .global _start _start: /* 1. led灯的初始化 *//* 1.1 使能GPIOE、DPIOF外设控制器的时钟 */ldr r0, 0x50000A28ldr r1, [r0]orr r1, r1, #(0x3 << 4)str r1, [r0]/* 1.2 设置PE10、PE8、PF10引脚为输出模式 */ldr r0, 0x50006000ldr r1, […

Redis到底是什么?都有哪些特性?看完这一篇就都会了

目录 Redis是什么 Redis的应用场景有哪些&#xff1f; Redis的数据类型及主要特性 Redis的数据结构 简单动态字符串SDS (Simple Dynamic String) SDS的特点 Redis特性1&#xff1a;事务 Redis特性2&#xff1a;发布订阅(Pub/Sub) Redis特性3&#xff1a;Stream Redis…

IntelliJ IDEA :解决 idea 导入项目爆红

IntelliJ IDEA &#xff1a;解决idea导入项目爆红 - LevelCoder的个人页面 - OSCHINA - 中文开源技术交流社区我们在导入一个新的项目到idea的时候,项目明明没有报错,但是会出现出了父包属于正常颜色外,其子包都会爆红色但是不属于项目本身错误,依旧可以正常启动,小编拿到入git…

C语言详细讲解#error与#line如何使用

C语言详细讲解#error与#line如何使用_C 语言_脚本之家 (jb51.net) 这篇文章主要介绍了C语言中#error与#line如何使用&#xff0c;#error与#line虽然在语言里面用的比较少&#xff0c;但是还是有必要了解一下 − 目录 一、#error 的用法二、#line 的用法三、小结 一、#error…

用于现场仪表过程控制的多协议配置工具

一 挑战 在现代生产环境中&#xff0c;我们会使用各种现场设备来记录过程数据&#xff08;从温度传感器到压力、液位和流量计&#xff09;&#xff0c;而这些数据需要通过多种通信协议来进行传输&#xff0c;例如HART、FOUNDATION Fieldbus或PROFIBUS PA。为此&#xff0c;每个…

找不到d3dx9_42.dll,无法继续执行代码怎么办?详解各种解决方法及注意事项

找不到d3dx9_42.dll,无法继续执行代码怎么办&#xff1f;首先&#xff0c;我们来解释一下d3dx9_42.dll文件是什么以及为什么会出现丢失的情况。在Windows操作系统中&#xff0c;d3dx9_42.dll是DirectX 9的一部分&#xff0c;它包含了许多DirectX 9图形函数的实现。这些函数被游…

VMware设置Linux网络

vmware提供了三种网络工作模式&#xff0c;Bridged&#xff08;桥接模式&#xff09;、NAT&#xff08;网络地址转换模式&#xff09;、Host-Only&#xff08;仅主机模式&#xff09;&#xff1a; vmware一般有两个虚拟网卡&#xff0c;VMnet1&#xff08;仅主机模式&#xff…

【Node.js】URL 模块

自动重启服务器的插件nodemon&#xff1a; npm i -g nodemon。或者 node-dev 也可以&#xff1a;npm i -g node-dev。 parse&#xff0c;format&#xff0c;resolve 为旧版写法。 parse import url from url const urlString https://www.baidu.com:443/ad/index.html?id8&a…

Beam Focusing for Near-Field Multi-User MIMO Communications阅读笔记

abstract 大天线阵列和高频段是未来无线通信系统的两个关键特征。大规模天线与高传输频率的组合通常导致通信设备在近场&#xff08;菲涅耳&#xff09;区域中操作。在本文中&#xff0c;我们研究了潜在的波束聚焦&#xff0c;可行的近场操作&#xff0c;在促进高速率多用户下…

基于SVM+TensorFlow+Django的酒店评论打分智能推荐系统——机器学习算法应用(含python工程源码)+数据集+模型(三)

目录 前言总体设计系统整体结构图系统流程图 运行环境模块实现1. 数据预处理2. 模型训练及保存3. 模型应用 系统测试1. 训练准确率2. 测试效果3. 模型应用 相关其它博客工程源代码下载其它资料下载 前言 本项目以支持向量机&#xff08;SVM&#xff09;技术为核心&#xff0c;…

[羊城杯 2020]easyser - 反序列化+SSRF+伪协议(绕过死亡die)

[羊城杯 2020]easyser 一、解题过程&#xff08;一&#xff09;、一阶段&#xff08;二&#xff09;、二阶段 二、思考总结 一、解题过程 &#xff08;一&#xff09;、一阶段 可以直接使用ctf-wscan扫描一下有什么文件&#xff0c;或者直接试试robots.txt能不能行 直接打开…

解锁精准营销的秘密武器:数据利器助您实现业务增长

在如今竞争激烈的市场环境中&#xff0c;营销人员面临着巨大的挑战。为了制定有效的营销策略&#xff0c;他们需要获取大量关键信息&#xff0c;了解目标客户的需求和偏好。然而&#xff0c;这些信息通常分散在各个网站和平台上&#xff0c;让营销人员花费大量时间和精力去搜集…

语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆

文章目录 mask图像介绍步骤代码 mask图像介绍 根据 mask 图像来画分割对象的外接椭圆是一种常见的图像分割任务。Mask 图像通常是一个二值图像&#xff0c;其中包含了感兴趣对象的像素。通常情况下&#xff0c;白色像素表示对象&#xff0c;黑色像素表示背景。 步骤 以下是一…

Sub-1 GHz、低噪声放大器芯片MS2630

MS2630 是一款 Sub-1 GHz 低功耗、低噪声放大器 (LNA) 芯 片。芯片采用先进制造工艺&#xff0c;采用 SOT23-6 的封装形式。 主要特点 ◼ 典型噪声系数&#xff1a;1.57dB ◼ 典型功率增益&#xff1a;16.3dB ◼ 典型输出 P1dB &#xff1a; -9.2dBm ◼ 工作频率&am…

PHP 伪协议:使用 php://input 访问原始 POST 数据

文章目录 参考环境PHP 伪协议概念为什么需要 PHP 伪协议&#xff1f; php://input为什么需要 php://input&#xff1f;更灵活的数据处理减小性能压力 发送 POST 数据HackBarHackBar 插件的获取 $_POST打开 HackBar 插件通过 HackBar 插件发起 POST 请求 基操 enable_post_data_…

【ElasticSearch】基于 Java 客户端 RestClient 实现对 ElasticSearch 索引库、文档的增删改查操作,以及文档的批量导入

文章目录 前言一、对 Java RestClient 的认识1.1 什么是 RestClient1.2 RestClient 核心类&#xff1a;RestHighLevelClient 二、使用 Java RestClient 操作索引库2.1 根据数据库表编写创建 ES 索引的 DSL 语句2.2 初始化 Java RestClient2.2.1 在 Spring Boot 项目中引入 Rest…

关系的性质(自反,反自反,对称,反对称,传递)

自反 若∀a∈A&#xff0c;必有<a,a>∈R&#xff0c;则称R是自反的&#xff0c;&#xff08;关系矩阵对角线都为1&#xff09;。 例&#xff1a;A{1,2,3}&#xff0c;R{<1,1,>,<2,2>,<3,3> 反自反 若∀a∈A&#xff0c;必有<a,a>R&#xff0c;…

微服务架构的未来:跨边界的云原生整合

文章目录 微服务架构的基础微服务的挑战云原生的崛起跨边界的云原生整合实现跨边界的云原生整合跨边界的云原生整合案例结论 &#x1f389;欢迎来到架构设计专栏~微服务架构的未来&#xff1a;跨边界的云原生整合 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&…