C++位图

一、前提引入

思考如何实现下面的题目 

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

一个整型数据int为4个字节,计算得 4*40e\approx 2^{34},大约需要16G的存储空间。如果采用遍历判断的话,时间复杂度为O(N)较高,并且不利于多次反复判断

如果采用二分查找,需要先排序再查找时间复杂度为O(logN)

由于只需要判断一个数是否存在,而无需存储数字本身。因此可以将用字节存储数据转换为用位标识,比特位为1则代表存在,如果比特位为0则代表不存在

字节最少的数据类型是char,所以采用vector存储char类型的数据。每个char包括一个字节,即8个比特位,每个比特位用于标识一个数字是否存在

因此将存储空间压缩为40亿/8=5亿个数据,也就是512MB的空间

二、位图

位图,就是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况。通常是用来判断某个数据存不存在的

位图其实是用数组实现的,数组的每一个元素的每一个二进制位都可以表示一个数据在或者不在,0表示数据存在,1表示数据不存在。因为比特位只有两种状态,要不是0,要不就是1,所以位图其实就是一种直接定址法的哈希,只不过位图只能表示这个值在或者不在

作用

1. 快速查找某个数据是否在一个集合中

2. 排序 + 去重

3. 求两个集合的交集、并集等

4. 操作系统中磁盘块标记

优点 :速度快节省空间

缺点:只能映射整型,其他类型比如浮点数、string等不能存储映射

三、程序实现

元素定位

位图是通过数组来实现的,因此首先需要定位所在的字节位置,然后在字节中定位相应的比特位置

通过以下代码来实现定位

			int i = x / 8;//判断字节位置int j = x % 8;//判断字节中的比特位位置

元素设置

在已经知道元素应该放置的位置后,需要将已知元素所在位置的比特位值更改为1

_bits[i] |= (1 << j);//这里的左移是指向高位移动

采用或运算,将1左移j位,采用按位或赋值,将其赋值为1,代表该数字存在

元素移出

与元素设置思路类似

_bits[i] &= ~(1 << j);//这里的左移是指向高位移动

采用与运算,将1左移j位,取反为0

#pragma once
#include<iostream>
#include<vector>using std::vector;namespace my_bitset
{template<size_t N>//N为需要存储的位数量class bitset{public:bitset(){_bits.resize(N / 8 + 1, 0);//向上取整}void set(){int i = x / 8;//判断字节位置int j = x % 8;//判断字节中的比特位位置_bits[i] |= (1 << j);//这里的左移是指向高位移动}void reset(size_t x){int i = x / 8;//判断字节位置int j = x % 8;//判断字节中的比特位位置_bits[i] &= ~(1 << j);//这里的左移是指向高位移动}bool test(size_t x){int i = x / 8;//判断字节位置int j = x % 8;//判断字节中的比特位位置return _bits[i] &= (1 << j);}private:vector<char> _bits;};
}
namespace my_bitset_2
{template<size_t N>class twobitset{public://将每个数据用两个比特位标识,如果是00则代表没有出现,如果为01则代表出现一次,10则代表出现一次以上void set(size_t x){//00->01if (_bs1.test(x) == false && _bs2.test(x) == false){_bs2.set(x);}//01->10else if (_bs1.test(x) == false && _bs2.test(x) == true){_bs1.set(x);_bs2.reset(x);}}private:my_bitset::bitset<N> _bs1;my_bitset::bitset<N> _bs2;};
}

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

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

相关文章

01-从JDK源码级别剖析JVM类加载机制

上一篇&#xff1a;JVM虚拟机调优大全 1. 类加载运行全过程 当我们用java命令运行某个类的main函数启动程序时&#xff0c;首先需要通过类加载器把主类加载到JVM。 public class Math {public static final int initData 666;public static User user new User();public i…

论文阅读 - Outlier detection in social networks leveraging community structure

目录 摘要 1. Introduction 2. Related works 3. Preliminaries 3.1. 模块化度量 3.2. Classes of outliers 3.2.1. 点异常 3.2.2. Contextual anomalies 3.2.3. Collective anomalies 3.3. Problem definition 3.4. Outliers score 4. Methodology 4.1. Proposed appr…

初识FUSE(Filesystem in userspace)

初识FUSE&#xff08;Filesystem in userspace&#xff09; 什么是FUSE&#xff1f;FUSE原理FUSE协议 如何去使用&#xff1f;参考文章 之前因为一次作业有幸接触过FUSE,觉得它是一个很不错的框架&#xff0c;没来得及仔细了解。现在有点时间了&#xff0c;想要利用它做一个文件…

Linux部署kettle并设置定时任务

一.安装Kettle linux中使用kettle时首先需要jdk环境&#xff0c;这里就不概述linux中jdk的安装与配置了。 1.首先将kettle压缩包放入linux并解压 unzip data-integration.zip kettle安装路径为:/root/Kettle9.3/data-integration 设置权限 chmod -R 755 /root/Kettle9.3/d…

LVS负载均衡群集NAT模式

LVS负载均衡群集NAT模式 一、集群与分布式1.1、集群的含义1.2、lvs模型1.3、系统性能扩展方式1.4、群集的三种类型1.4.1、负载均衡群集1.4.2、高可用群集1.4.3、高性能运算群集 1.5、LVS的负载调度算法1.5.1、轮询1.5.2、加权轮询1.5.3、最少连接1.5.4、加权最少连接1.5.5、ip_…

pc端测试手机浏览器运行情况,主要是测试硬件功能

测试h5震动摇晃等功能时不方便测试&#xff0c;需要连电脑显示调试数据 方法&#xff1a; 1.需要手机下载谷歌浏览器&#xff0c;pc端用edge或这谷歌浏览器 2.手机打开USB调试&#xff0c;打开要测试的网页 3.pc端地址栏输入edge://inspect/#devices&#xff08;这里用的edge浏…

K8S:kubeadm搭建K8S+Harbor 私有仓库

文章目录 一.部署规划1.主机规划2.部署流程 二.kubeadm搭建K8S1.环境准备2.安装docker3. 安装kubeadm&#xff0c;kubelet和kubectl4.部署K8S集群&#xff08;1&#xff09;初始化&#xff08;2&#xff09;部署网络插件flannel&#xff08;3&#xff09;创建 pod 资源 5.部署 …

Linux HTTP协议

目录 1.浏览器与服务器通信过程2.HTTP请求报头&#xff08;1&#xff09;HTTP的请求报头结构&#xff08;2&#xff09;HTTP的请求方法 3.HTTP应答报头&#xff08;1&#xff09;HTTP的应答报头结构&#xff08;2&#xff09; HTTP的应答状态 1.浏览器与服务器通信过程 浏览器…

回归预测 | MATLAB实现PSO-SDAE粒子群优化堆叠去噪自编码器多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现PSO-SDAE粒子群优化堆叠去噪自编码器多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现PSO-SDAE粒子群优化堆叠去噪自编码器多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览…

清理Maven仓库中下载失败的文件

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Nginx详解 五:反向代理

文章目录 1. 正向代理和反向代理1.1 正向代理概述1.1.1 什么是正向代理1.1.2 正向代理的作用1.1.3 正向代理的基本格式 1.2 反向代理概述1.2.1 什么是反向代理1.2.2 反向代理可实现的功能1.2.3 反向代理的可用模块 2. 配置反向代理2.1 反向代理配置参数2.1.1 proxy_pass2.1.2 其…

原型模式简介

概念&#xff1a; 原型模式 (Prototype Pattern)是一种创建型设计模式&#xff0c;它允许通过复制现有对象来创建新对象&#xff0c;而无需依赖于昂贵的实例化过程。该模式基于原型实例生成新的对象&#xff0c;并且可以根据需要进行修改和定制。 特点&#xff1a; 通过克隆…

当你的公司突然开始大量的裁员,被留下的你,真的准备好面对以后了吗?

留下来的&#xff0c;也是迷茫的 最近公司突然开始大量裁员&#xff0c;裁了一多半&#xff0c;作为唯一留下的APP 端开发人员&#xff0c;也开始陷入了焦虑&#xff0c;开始了思考&#xff0c;未来究竟何去何从&#xff0c;是否再去转到原生&#xff0c;从事原生的开发工作&a…

C语言入门Day_19 初识函数

目录 1.函数的定义 2.函数的调用 3.易错点 4.思维导图 前言&#xff1a; printf()我们已经很熟悉了&#xff0c;它有一个特定的功能&#xff0c;就是在屏幕上输出一行文字。之前的课程我们都称呼printf()为一个功能&#xff0c;实际上ta在编程中有个特定的名字——函数。 …

测试-----selenuim webDriver

文章目录 1.页面导航2.元素定位3. 浏览器操作4.获取元素信息5. 鼠标的操作6. 键盘操作7. 元素等待8.下拉框9.弹出框10.滚动条11.frame处理12.验证码处理&#xff08;cookie&#xff09; 1.页面导航 首先是导入对应的包 :from selenium import webdriver然后实例化:driver web…

MySQL——库和表的增删改

2023.9.12 本章学习DDL&#xff08;数据定义语言&#xff09;语言&#xff0c;相关笔记&#xff1a; #DDL /*数据定义语言库和表的管理一、库的管理 创建、修改、删除 二、表的管理 创建、修改、删除创建&#xff1a; create 修改&#xff1a; alter 删除&#xff1a; drop*/#…

标准C++day5——静态成员和单例模式(饿汉、懒汉)

一、静态成员 什么是静态成员&#xff1a; 被static修饰的成员变量和成员函数就叫静态成员 普通成员的特点&#xff1a; 成员变量&#xff1a;每个类对象中都有一份属于自己的成员变量&#xff0c;相互之间没有关联、独立的 成员函数&#xff1a;隐藏着一个this指针&#xff0c…

网络安全宣传周|探索AI数字人的魅力和价值所在

9月11日至9月17日是国家网络安全宣传周&#xff0c;在福州举办的安全博览会上有着多种人工智能模型产品亮相现场&#xff0c;吸引着众多参观者的目光&#xff0c;尤其是AI数字人面对不同的问题、不同的场景都可以进行实时响应&#xff0c;不同于冷冰冰的传统智能客服的对话场景…

2023-09-05力扣每日一题

链接&#xff1a; 2605. 从两个数字数组里生成最小数字 题意&#xff1a; 两个数组都只包含1-9的数字&#xff0c;求一个最小数&#xff0c;两个数组内都要有它的其中一位 解&#xff1a; 要么是个位数要么是十位数&#xff0c;存一下数量和两边的最小数即可 实际代码&am…

前端面试合集(二)

前端面试题合集 1.懒加载的原理及实现了解吗2.如何理解JS异步3.阐述一下 JS 的事件循环4.JS 中的计时器能做到精确计时吗&#xff1f;为什么&#xff1f; 1.懒加载的原理及实现了解吗 原理&#xff1a;当图片没有到达可视范围内时&#xff0c;图片不加载&#xff0c;当图片一旦…