位图

例题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)

大家都在看

  • bash 教程-1 shell 基础 快捷键 目录堆栈 操作历史 [MD]

    我的GitHub 我的博客 我的微信 我的邮箱 bqt20094 baiqiantao@sina.com Bash 简介 Bash 是 Unix 系统和 Linux 系统的一种 S…

    Linux 2023年5月28日
    098
  • nginx 修改文件上传大小限制

    修改nginx的配置文件,添加client_max_body_size 字段 注:client_max_body_size必须要放在server下的server_name下,而不是…

    Linux 2023年6月8日
    0103
  • kali linux安装vulhub

    镜像下载、域名解析、时间同步请点击阿里云开源镜像站 Vulhub是一个基于docker和docker-compose的漏洞环境集合,进入对应目录并执行一条语句即可启动一个全新的漏洞…

    Linux 2023年6月7日
    0113
  • 面试题目汇总

    目录: 1、数字数组数字数组2、字符串字符串3、链表 链表4、二叉树二叉树 5、堆栈 堆栈 posted @2019-12-11 20:35 风御之举 阅读(63 ) 评论() 编…

    Linux 2023年6月13日
    095
  • 【深度学习】神经网络前向传播简单实现

    步骤 输入层的每个节点与隐藏层的每个节点做点对点计算,加权求和 + 激活函数 利用同样的方法,计算隐藏层到输出层 隐藏层对加权结合后的结果使用激活函数,本例使用Sigmoid 最终…

    Linux 2023年6月13日
    0107
  • 【spring-boot】配置Redis工具类

    如何在spring-boot中使用Redis工具类 修改pom.xml文件 新增spring-boot-starter-data-redis配置 org.springframewo…

    Linux 2023年5月28日
    0111
  • Android下获取FPS的几种方法

    FPS(Frames Per Second)是关乎Android用户体验最为重要的指标之一,而在VR中更是如此。为了评估VR系统、VR SDK及Unity应用的性能,通常会实时获取…

    Linux 2023年6月7日
    0101
  • redis安装使用

    Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 它通常被称为数据结构服务…

    Linux 2023年5月28日
    0103
  • redis

    ./redis-cli -a 111 KEYS "key*" | xargs ./redis-cli -a 111 DEL Original: https://…

    Linux 2023年5月28日
    0100
  • Bash shell

    例一: 函数、返回状态值、比较 #!/bin/bash NUM=$(date +%S) echo "当前苹果价格是每斤$NUM元" echo "===…

    Linux 2023年5月28日
    091
  • python之pyautogui实现图片识别-办公自动化

    环境 python 3.8everedit编辑器 代码 from selenium import webdriver from selenium.webdriver.chrome….

    Linux 2023年6月7日
    0119
  • 用 shell 脚本制造连接频繁中断的场景

    问题的提出 最近在准备客户端的新版本,在内部灰度过程中,发现一类奇怪的 dump,通过查看日志和堆栈,可以确定是因为每次连上后台就被后台断开了、导致多次重连后随机发生的崩溃。dum…

    Linux 2023年6月6日
    094
  • 关于在Rocky linux下安装dotnet sdk不成功的问题

    Rocky Linux 9,运行 dnf install -y dotnet-sdk-6.0 一切正常,运行起来非常顺利,安装完毕。但是非常诡异,运行 dotnet –list-…

    Linux 2023年6月6日
    0125
  • 对抗攻击方法BIM与PGD的区别

    Basic iterative method(BIM):论文地址 笔记地址 Projected gradient descent(PGD):论文地址 笔记地址 区别1 来自于:ht…

    Linux 2023年6月7日
    0108
  • [转帖]bash shell学习之变量

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年5月28日
    096
  • 【Docker搭建】0. 在CentOS下安装/卸载Docker

    警告:切勿在没有配置 Docker YUM 源的情况下直接使用 yum 命令安装 Docker. 系统要求Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本…

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