位图

例题1

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

首先肯定不能用传统的int数据存储 因为内存不够 40亿的整数大概为16G左右

思路1: 因为byte位数据小 1字节就有8个byte 那么40亿byte数据大概只有500mb左右

    template//先开好总有数据大小
    class moxuan_bit
    {
    public:
        //开空间
        moxuan_bit()
        {
            //char类型有8个字节  所以N个数据就/8即可  假如开10 只开了一个char  不够 所以
            //要+1
            _bits.resize(N / 8 + 1, 0);
        }

        //把x映射的位置标记成1  表示存在
        void set(size_t x)
        {
            //计算在第几个char范围内
            size_t i = x / 8;

            //计算在第i个char范围内的第几个
            size_t j = x % 8;

            _bits[i] |= (1 << j);
        }

        void reset(size_t x)
        {
            //计算在第几个char范围内
            size_t i = x / 8;

            //计算在第i个char范围内的第几个
            size_t j = x % 8;

            //将第j个数改为1  然后取反  其他bit位变为1  j的数变为0
            //这时候 按位与  其他比特位为不变  j的比特位为0  就删除了这个值不存在
            _bits[i] &= (~(1 << j));
        }

        bool test(size_t x)
        {
            //计算在第几个char范围内
            size_t i = x / 8;

            //计算在第i个char范围内的第几个
            size_t j = x % 8;

            //如果跟1是相同 就返回1 true  如果跟1不相同 就返回0 false
            //并且不是&= 不会改变里面的值
            return _bits[i] & (1 << j);

        }

    private:
        std::vector<char> _bits;
    };

位图

测试:

    void test1()
    {
        moxuan_bit<100> v;
        v.set(20);
        v.set(77);
        v.set(0);

        cout << v.test(20) << " " << v.test(77) << " " << v.test(0) << endl;

        v.reset(0);

        cout << v.test(20) << " " << v.test(77) << " " << v.test(0) << endl;
    }

例题2:

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

思路 :用两个位图表示 大概数据量为 1G

template
    class two_bit
    {
    public:
        void set(size_t x)
        {
            //返回它的状态 1或 0
            int in1 = bit1.test(x);
            int in2 = bit2.test(x);
            //当两个都为0 状态改为 0 1
            if (in1 == 0 && in2 == 0)
            {
                bit2.set(x);
            }
            //当为 01 存在时 又遇到了  就改为 10  表示存在1次以上
            else if(in1==0&&in2==1)
            {
                bit1.set(x);
                bit2.reset(x);
            }
        }

        //如果该值为  0 1 表示就存在过一次
        bool is_once(size_t x)
        {
            return bit1.test(x) == 0 && bit2.test(x) == 1;
        }

    private:
        //用两个位图表示3种状态   0  0 表示不存在 0 1 表示存在一次 1 0 表示存在一次以上
        moxuan_bit bit1;
        moxuan_bit bit2;
    };

测试:

    void test2()
    {
        two_bit<13> v1;
        int a[] = { 5,8,9,2,5,9,4,2,1,0,7,6,5 };

        for (auto e : a)
        {
            v1.set(e);
        }

        for (int i = 0; i 10; i++)
        {
            if (v1.is_once(i))
            {
                cout << i << " ";
            }
        }
    }

&按位与
按位”与”运算符 (&) 会将第一操作数的每一位与第二操作数的相应位进行比较。如果两个位均为 1,则对应的结果位将设置为 1。否则,将对应的结果位设置为 0。
| 按位或:
按位”与或”运算符 (|) 将第一个操作数的每个位与第二个操作数的对应位进行比较。如果其中一个位是 1,则将对应的结果位设置为 1。否则,将对应的结果位设置为 0。
^ 按位异或:
按位”异或”运算符 (^) 将第一操作数的每个位与第二操作数的相应位进行比较。如果一个位是 0,另一个位是 1,则相应的结果位将设置为 1。否则,将对应的结果位设置为 0。
~取反:
若操作数为1 设置为0 若为1 则设置为1
>>右移 实际不是向右移动 而是向低位移动
<

Original: https://www.cnblogs.com/LonelyMoNan/p/16697538.html
Author: lemon-Breeze
Title: 位图

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/607395/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Windows 10安装

    使用U盘安装操作系统教程 本教程介绍如何使用U盘安装操作系统,以安装Windows 10过程作为举例。 1 获取操作系统iso镜像文件 获取操作系统ISO镜像文件有很多途径,此处介…

    Linux 2023年6月13日
    091
  • Spring Boot 项目部署到 Linux服务器

    1.首先将SpringBoot项目打包成JAR包,然后通过FTP工具上传到Linux,执行如下命令: java -jar xxx.jar & 该命令执行后,启动jar,一旦…

    Linux 2023年6月14日
    069
  • JAVA实现微信小程序支付退款功能

    JAVA实现微信小程序支付退款功能 本如亲测有效(代码复制直接可以用的),退款的前提是必须有小程序的appid、商户号、商户密匙、和证书、 这个是微信小程序退款的官网大家可以去看看…

    Linux 2023年6月7日
    0209
  • 渐变色搭配网站(模仿)

    html;gutter:true; 渐变色</p> <pre><code> * { margin: 0; } body { display: f…

    Linux 2023年6月13日
    085
  • springboot redis key乱码

    原写法: 写入redis后,查看key值 解决方式: 调整后查看redis key值: Original: https://www.cnblogs.com/janes/p/8796…

    Linux 2023年5月28日
    090
  • 高级IPC DBus

    404. 抱歉,您访问的资源不存在。 可能是URL不正确,或者对应的内容已经被删除,或者处于隐私状态。 [En] It may be that the URL is incorre…

    Linux 2023年5月27日
    0102
  • CPU架构对redis的性能影响

    CPU架构对redis的性能影响 主流CPU架构 一个CPU处理器中通常有多个运行核心,每一个运行核心称为一个物理核,每个物理核都可以运行应用程序。每个物理核都拥有 私有的一级缓存…

    Linux 2023年5月28日
    0102
  • Centos 7 升级内核

    【背景说明】 在公司进行部署产品时,发公司内部的服务内核资源并不能满足于产品部署条件,于是我和内核就进行了一场风花雪月般的交互,在操作前,本人小白一枚,就在浩瀚的互联网海洋中搜索升…

    Linux 2023年5月27日
    096
  • 常见题目

    这几天有朋友反映给小编说让多发点关于面试的文章,小编深知从事IT行业的难处,跳槽多,加班多,薪资不乐观,大多数朋友都想找新的工作,进入一个好的公司,今天小编就给大家带来了C语言面试…

    Linux 2023年6月13日
    093
  • Mac下安装zshell

    什么是shell 大多数命令行用户接触最多的是Bash,因为Bash是各个版本操作系统(Linux&Mac)的默认shell。 查看当前使用的shell $ echo $S…

    Linux 2023年5月28日
    082
  • 使用MyBatis Generator代码生成器的简单模式

    在动态web项目的lib目录下放入mybatis-3.2.2jar、mysql-connector-java-5.1.25-bin.jar、log4j-1.2.17.jar还有生成…

    Linux 2023年6月8日
    0112
  • 通过shell命令在MAC安装证书

    Macmini打包要需要更新苹果证书,又不想连接显示器,鼠标点点,如果可以通过shell命令,直接远程安装证书就好了。 #双击证书文件 open #输入密码 security un…

    Linux 2023年5月28日
    0122
  • 【论文笔记】(知识蒸馏)Distilling the Knowledge in a Neural Network

    摘要 模型平均可以提高算法的性能,但是计算量大且麻烦,难以部署给用户。《模型压缩》这篇论文中表明,知识可以从复杂的大型模型或由多个模型构成的集成模型中压缩并转移到一个小型模型中,本…

    Linux 2023年6月7日
    0169
  • Java实现链表

    3、链表 MyLinkedList 有一个头指针,一个尾指针,还有链表长度size 内有两个类,一个是实现了Iterator接口的迭代器类,另一个是Node类,其中Node数据结构…

    Linux 2023年6月14日
    090
  • 如何验收安卓PCBA主板的质量和性能

    .版本:v0.1作者:河东西望日期:2022-7-15. 对很多安卓智能设备厂商来说,他们的通用开发模式一般是:ODM/OEM设计开发主板PCBA(包括BSP驱动、原生AOSP系统…

    Linux 2023年6月7日
    0103
  • Java — 注解

    Java 注解(Annotation)又称为 Java 标注,是 Java5 开始支持加入源代码的特殊语法元数据。 Java 语言中的类、方法、变量、参数和包等都可以被标注。 Ja…

    Linux 2023年6月8日
    091
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球