【数据结构】哈希经典应用:位图——[深度解析](8)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【数据结构】哈希经典应用:位图——[深度解析](8)

一.位图的基本概念

  • 所谓位图,就是用 每一位 来存放某种状态,适用于海量数据,数据无重复的场景。
  • 通常是用来判断某个数据存不存在的

二.位图的原理

  • 哈希—— 直接定址法
  • 例:
  • 在实际场景中,我们的机器一般是 小端机(从左到右,从大到小排布)
  • 所以真正的场景一般如下:
  • 小端机性质 证明:

三.位图(bitset)的代码实现(逐过程解读)

【1】位图的文档查看

  • 我们可以重点关注红圈圈出的三个位图常用函数

【2】把X映射的那个标记成1——对应biteset中的set

【3】把X映射的那个标记成0——对应biteset中的reset

【4】判断某位是1还是0——对应biteset中的test

【5】位图的完整实现

#include<vector>
namespace bit
{
  template<size_t N>
  class bitset
  {
  public:
    bitset()
    {
      _a.resize(N / 32 + 1);//位图的初始化,确定分为多少块
    }
    // x映射的那个标记成1
    void set(size_t x)
    {
      size_t i = x / 32;
      size_t j = x % 32;
      _a[i] |= (1 << j);
    }
    // x映射的那个标记成0
    void reset(size_t x)
    {
      size_t i = x / 32;
      size_t j = x % 32;
      _a[i] &= (~(1 << j));
    }
    bool test(size_t x)
    {
      size_t i = x / 32;
      size_t j = x % 32;
      return _a[i] & (1 << j);
    }
  private:
    vector<int> _a;
  };
}

四.位图的经典应用场景

【※】对数据大小&转换的基本概念

  • 1G =1024 MB=10241024 BK=10241024*1024 Byte= 2^30 byte = 10亿+ byte
  • 例:我们判断40亿个整数需要多少G呢?
    分析:40亿个int,160亿byte,根据10亿byte对应1G,160亿byte对应16G

【1】给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中?

  • 分析:常规思路是遍历/排序+二分查找
  • 遍历的时间复杂度是O(N),排序(O(NlogN))+二分查找 logN
  • 显然对于40亿无符号整数来说,需要占用16G,占用资源过于庞大,不妥
  • 快速判断在不在,显然是位图经典场景,利用位图解决:
  • 数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。比如:

【2】给定100亿个整数,设计算法找到只出现一次的整数

  • 分析:我们可以用两个位图来控制,我们可以这样设计
  • 代码展示设计思路如图所示:
template<size_t N>
  class twobitset
  {
  public:
    void set(size_t x)
    {
      // 00 -> 01
      if (!_bs1.test(x) && !_bs2.test(x))
      {
        _bs2.set(x);
      } // 01 -> 10
      else if (!_bs1.test(x) && _bs2.test(x))
      {
        _bs1.set(x);
        _bs2.reset(x);
      }
      // 本身10代表出现2次及以上,就不变了
    }
    bool is_once(size_t x)
    {
      return !_bs1.test(x) && _bs2.test(x);
    }
  private:
    bitset<N> _bs1;
    bitset<N> _bs2;
  };

【3】位图应用变形:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数

  • 此题的设计思路与上面的【2】基本一致,设计上要稍作改动:
  • 代码展示设计思路如图所示:
template<size_t N>
  class twobitset
  {
  public:
    void set(size_t x)
    {
      // 00 -> 01
      if (!_bs1.test(x) && !_bs2.test(x))
      {
        _bs2.set(x);                        //出现一次
      } // 01 -> 10
      else if (!_bs1.test(x) && _bs2.test(x))
      {
        _bs1.set(x);
        _bs2.reset(x);                    //出现两次
      }// 10 -> 11
      else if (_bs1.test(x) && !_bs2.test(x))
      {
        _bs2.set(x);                      //出现三次
      }
      // 此外代表出现3次及以上,就不变了
    }
    bool max_two(size_t x)
    {
      return (_bs1.test(x) && !_bs2.test(x))||(!_bs1.test(x) && _bs2.test(x));   //10 或者 01
    }
  private:
    bitset<N> _bs1;
    bitset<N> _bs2;
  };

【4】给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件的交集?

  • 分析:
  • 第一种思路是:把其中一个文件存入位图,遍历另一个文件元素,将问题转变成"在不在"问题
  • 问题缺陷: 这种问题存在去重问题,即多次重复(下图中,交集明明只有一个3,但是会出现多个重复的3交集)
  • 分析:
  • 第二种思路是:将两个文件映射到两个位图中去(实现去重)
  • 如果相对应的位置都是1(满足相&为1),则此元素就在交集中


相关文章
RS-485网络中的标准端接与交流电端接应用解析
RS-485,作为一种广泛应用的差分信号传输标准,因其传输距离远、抗干扰能力强、支持多点通讯等优点,在工业自动化、智能建筑、交通运输等领域得到了广泛应用。在构建RS-485网络时,端接技术扮演着至关重要的角色,它直接影响到网络的信号完整性、稳定性和通信质量。
|
13天前
|
自然语言处理 并行计算 数据可视化
免费开源法律文档比对工具:技术解析与应用
这款免费开源的法律文档比对工具,利用先进的文本分析和自然语言处理技术,实现高效、精准的文档比对。核心功能包括文本差异检测、多格式支持、语义分析、批量处理及用户友好的可视化界面,广泛适用于法律行业的各类场景。
|
7天前
|
存储 供应链 物联网
深入解析区块链技术的核心原理与应用前景
深入解析区块链技术的核心原理与应用前景
|
7天前
|
存储 供应链 安全
深度解析区块链技术的核心原理与应用前景
深度解析区块链技术的核心原理与应用前景
16 0
|
11天前
|
SQL 监控 安全
员工上网行为监控软件:SQL 在数据查询监控中的应用解析
在数字化办公环境中,员工上网行为监控软件对企业网络安全和管理至关重要。通过 SQL 查询和分析数据库中的数据,企业可以精准了解员工的上网行为,包括基础查询、复杂条件查询、数据统计与分析等,从而提高网络管理和安全防护的效率。
24 0
|
7天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
23 2
|
1月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
67 0
|
1月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
54 0
|
1月前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
60 0
|
1月前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
83 0

热门文章

最新文章

推荐镜像

更多