【STL】bitset的模拟实现

news2024/12/23 16:29:46

⭐博客主页:️CS semi主页
⭐欢迎关注:点赞收藏+留言
⭐系列专栏:C++进阶
⭐代码仓库:C++进阶
家人们更新不易,你们的点赞和关注对我而言十分重要,友友们麻烦多多点赞+关注,你们的支持是我创作最大的动力,欢迎友友们私信提问,家人们不要忘记点赞收藏+关注哦!!!

bitset的模拟实现

  • 一、函数接口总览
  • 二、bitset类的实现
    • 1、构造函数
    • 2、set(设置)
    • 3、reset(重置)
    • 4、flip(反转)
    • 5、test(获取位状态)
    • 6、size(算长度/个数)
    • 7、count(算位图中被设置的个数)
    • 8、any(该位图中是否有位被设置)
    • 9、none(判断位图中是否全部位都没有被设置)
    • 10、all(判断是否全被设置)
    • 11、Print(打印函数)


一、函数接口总览

#include<vector>
#include<iostream>
using namespace std;

namespace JRH
{
	// 模拟实现位图
	template<size_t N>
	class bitset
	{
	public:
		// 构造函数
		bitset();

		// set设置位
		void set(size_t pos);

		// reset清空
		void reset(size_t pos);

		//反转位
		void flip(size_t pos);

		//获取位的状态
		bool test(size_t pos);

		//获取可以容纳的位的个数
		size_t size();

		//获取被设置位的个数
		size_t count();

		//判断位图中是否有位被设置
		bool any();

		//判断位图中是否全部位都没有被设置
		bool none();

		//判断位图中是否全部位都被设置
		bool all();

		//打印函数
		void Print();

	private:
		vector<int> _bits;
	};
}

二、bitset类的实现

1、构造函数

在构造位图时,我们需要根据所给位数N,创建一个N位的位图,并且将该位图中的所有位都初始化为0。

我们知道,一个整型有32个比特位,但我们传来的位图肯定不可能是32的倍数的,所以我们就需要在结束完/32以后就加1,往后多开一个32个位的空间,将多余的空间放到下一个位图中。

如下图:我们假如有40位,我们则需要开两个整型(多开一个),并将这40放进去。
在这里插入图片描述

		// 构造函数
		bitset()
		{
			_bits.resize(N / 32 + 1, 0);
		}

2、set(设置)

在这里插入图片描述

		// set设置位
		void set(size_t pos)
		{
			assert(pos < N);
			// 除一下找到在第几个
			int i = pos / 32;
			int j = pos % 32;
			_bits[i] |= (1 << j);
		}

3、reset(重置)

在这里插入图片描述

		// reset清空
		void reset(size_t pos)
		{
			assert(pos < N);

			// 除一下找到在第几个
			int i = pos / 32;
			int j = pos % 32;
			_bits[i] &= (~(1 << j));
		}

4、flip(反转)

在这里插入图片描述

		//反转位
		void flip(size_t pos)
		{
			assert(pos < N);

			// 找到在哪里
			int i = pos / 32;
			int j = pos % 32;
			_bits[i] ^= (1 << j);
		}

5、test(获取位状态)

在这里插入图片描述

		//获取位的状态
		bool test(size_t pos)
		{
			assert(pos < N);

			// 找到位置
			int i = pos / 32;
			int j = pos % 32;
			if (_bits[i] & (1 << j))
				return true;
			else
				return false;
		}

6、size(算长度/个数)

size成员函数用于获取位图中可以容纳的位的个数,即直接计算参数模板中的位的个数即可。

		//获取可以容纳的位的个数
		size_t size()
		{
			return N;
		}

7、count(算位图中被设置的个数)

在这里插入图片描述

		//获取被设置位的个数
		size_t count()
		{
			size_t count = 0;
			for (auto e : _bits)
			{
				int num = e;
				// 计算1的个数
				while (num)
				{
					num = num & (num - 1);
					count++;
				}
			}
			return count;
		}

8、any(该位图中是否有位被设置)

只需要一个for循环,如果有一个是1则返回true,遍历结束都没有1则返回false。

		//判断位图中是否有位被设置
		bool any()
		{
			for (auto e : _bits)
			{
				if (e != 0)
				{
					return true;
				}
			}
			return false;
		}

9、none(判断位图中是否全部位都没有被设置)

只需要返回any的逻辑取反即可。

		//判断位图中是否全部位都没有被设置
		bool none()
		{
			return !any();
		}

10、all(判断是否全被设置)

1、先检查前n-1个整数的二进制是否为全1
2、再检查最后一个整数的前N%32个比特位是否为全1

在这里插入图片描述

		//判断位图中是否全部位都被设置
		bool all()
		{
			size_t n = _bits.size();
			// 先判断前n-1个整数
			for (size_t i = 0; i < n - 1; ++i)
			{
				// 取反后不全为0则取反前不全为1
				if (~_bits[i] != 0)
				{
					return false;
				}
			}
			// 再判断第n个整数的bite位
			for (size_t j = 0; j < N % 32; j++)
			{
				if ((_bits[n - 1] & (1 << j)) == 0)
				{
					return false;
				}
			}
			return true;
		}

11、Print(打印函数)

打印函数就是先打印前n-1个数值的比特位的值,再打印最后一个整数的32个比特位中前面被设置的值。

		//打印函数
		void Print()
		{
			int count = 0;
			size_t n = _bits.size();

			// 先打印前n-1
			for (int i = 0; i < n - 1; i++)
			{
				for (int j = 0; j < 32; j++)
				{
					if (_bits[i] & (1 << j))
					{
						cout << "1";
					}
					else
					{
						cout << "0";
					}
					count++;
				}
			}

			// 再打印第n个的比特位
			for (int j = 0; j < N % 32; j++)
			{
				if (_bits[n - 1] & (1 << j))
				{
					cout << "1";
				}
				else
				{
					cout << "0";
				}
				count++;
			}
			cout << endl;
			cout << " " << count << endl;
		}

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

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

相关文章

HTML5有哪些新特性?移除了哪些元素?

HTML5引入了许多新特性&#xff0c;以下是其中一些主要的新特性&#xff1a; 1&#xff1a;语义化元素&#xff1a;HTML5引入了一些新的语义化元素&#xff0c;如 <header>、<footer>、<nav>、<article>、<section>等&#xff0c;使得页面结构…

计算机组成原理 new09 定点数的移位运算

文章目录 原码/正数反码/正数补码的算术移位负数反码的算术移位负数补码的算术移位算术移位总结符号扩展算术移位的应用真值的算术移位逻辑移位逻辑移位的运用 循环移位不带进位位的循环移位(小循环)带进位位的循环移位(大循环)原码定点一位乘法原码定点一位乘法(手算) (这里我…

【Qt控件之QToolBox】介绍及使用

概述 QToolBox类提供了一个列式的带有选项卡的小部件条目。工具箱是一个小部件&#xff0c;以一个列式的选项卡显示在上方&#xff0c;并在当前选项卡下方显示当前的小部件条目。每个选项卡在选项卡列中有一个索引位置。选项卡的小部件条目是一个QWidget。 每个小部件条目都有…

婚纱摄影行业,还在使用电梯广告?不如试试大数据精准营销

以武汉为例&#xff0c;婚纱摄影的以薇拉&#xff0c;青禾&#xff0c;韩国艺匠&#xff0c;果石&#xff0c;等品牌为主&#xff0c;竞争尤其惨烈&#xff0c;婚纱摄像婚庆行业主要依赖于线下推广&#xff08;如依靠与酒店、婚礼策划等上下游产业合作&#xff09;&#xff0c;…

Google Colab免费GPU使用教程

目录 前言一、Google Colab介绍二、使用步骤1、创建谷歌云盘2、创建一个新的Colab Notebook3、设置免费的GPU4、挂载Google Drive5、运行代码 三、防止掉线措施四、参考 前言 有时候本地跑代码可能耗时比较久&#xff0c;而且还会耽误你本地电脑的使用&#xff0c;购买云服务器…

智能矩阵系统解决的问题?

智能矩阵系统可以解决的问题多种多样&#xff0c;它主要通过人工智能技术应用于矩阵系统&#xff0c;解决一些传统方法难以处理的问题。 以下是一些常见的应用场景&#xff1a; 1. 数据管理&#xff1a;智能矩阵系统可以有效地管理大量的数据&#xff0c;包括数据的存储、检索…

【已解决】Unity 使用NPOI 写word文档报错:System.TypeLoadException:……0.86.0.518

报错显示 System.TypeLoadException: Could not resolve type with token 01000080 from typeref (expected class ICSharpCode.SharpZipLib.Zip.UseZip64 in assembly ICSharpCode.SharpZipLib, Version0.86.0.518, Cultureneutral, PublicKeyToken1b03e6acf1164f73) at NPOI.…

C++初阶--类与对象(1)

文章目录 类的引入类的定义访问限定符类成员的注意事项变量名的冲突 类的实例化类成员的声明与定义类的大小this指针特性 总结 类的引入 在c语言中&#xff0c;我们会这样写一个栈&#xff1a; struct Stack {int* a;int top;int capacity; };void StackInit(struct Stack* p…

利用Bootstrap的分页组件实现分页效果

在网页开发过程中&#xff0c;如果碰到内容过多的情况&#xff0c;一般都会使用分页处理。 在<ul>元素上添加pagination类&#xff0c;在<li>元素上添加page-item类&#xff0c;在超链接中添加 page-link类&#xff0c;即可实现一个简单的分页。 目录 00-基础知识…

STM32项目工程的搭建

视频连接&#xff1a; [2-1]--入门 新建工程 及 工程搭建 -------------_哔哩哔哩_bilibili 1.STM32开发方式 1.标志库 表示直接调用已经写好的程序&#xff0c;通过类似于函数调用直接使用即可。 2.HAL库 程序员自己手动的操作寄存器进行编程 2.工程模板 3.搭建工程的步骤 1…

微信小程序OA会议系统数据交互

前言 经过我们所写的上一文章&#xff1a;微信小程序会议OA系统其他页面-CSDN博客 在我们的是基础面板上面&#xff0c;可以看到出来我们的数据是死数据&#xff0c;今天我们就完善我们的是数据 后台 在我们去完成项目之前我们要把我们的项目后台准备好资源我放在我资源中&…

Memcached和Memcache安装(64位win10)

Memcached和Memcache安装&#xff08;64位win10&#xff09; 一、Memcached和Memcache的区别&#xff1a;   网上关于Memcached和Memcache的区别的理解众说纷纭&#xff0c;我个人的理解是&#xff1a;   Memcached是一个内存缓存系统&#xff0c;而Memcache是php的一个扩展…

虚假KeePass网站利用Google Ads和Punycode推送恶意软件

导语 近日&#xff0c;一起利用Google Ads和Punycode进行恶意软件传播的事件引起了广泛关注。该事件利用虚假KeePass下载网站&#xff0c;通过Punycode编码伪装成KeePass密码管理器的官方域名&#xff0c;并在Google Ads广告中推广&#xff0c;诱导用户下载恶意软件。这种新型的…

C++初阶(四)类和对象

文章目录 一、面向过程和面向对象初步认识二、类的引入三、类的定义1、类的概述2、类的两种定义3、成员变量命名规则的建议 四、类的访问限定符及封装1、访问限定符2、封装 五、类的作用域六、类的实例化七、类对象模型1、如何计算类对象的大小2、 类对象的存储方式猜测3、 验证…

【rust/树莓派】使用rppalembedded-graphics控制st7789 LCD屏幕

说在前面 树莓派版本&#xff1a;4bLCD模块&#xff1a;ST7789V2 240*280 LCD树莓派系统&#xff1a;Linux raspberrypi 5.15.76-v8 #1597 SMP aarch64 GNU/Linuxrust版本&#xff1a;rustc 1.73.0 模块详情 某雪的1.69inch LCD模块&#xff0c;包含杜邦线 准备工作 树莓派…

JavaSE编程题目练习(一)

博客昵称&#xff1a;架构师Cool 最喜欢的座右铭&#xff1a;一以贯之的努力&#xff0c;不得懈怠的人生。 作者简介&#xff1a;一名Coder&#xff0c;欢迎关注小弟&#xff01; 博主小留言&#xff1a;哈喽&#xff01;各位CSDN的uu们&#xff0c;我是你的小弟Cool&#xff0…

Rust 中的String与所有权机制

文章目录 一、string二、所有权2.1 所有权与作用域2.2 对所有权的操作2.2.1 转移2.2.3 拷贝2.2.3 传递 2.3 引用2.3.1 借用2.3.2 可变引用 一、string 之前学习过 Rust 只有几种基础的数据类型&#xff0c;但是没有常用的字符串也就是String&#xff0c;今天来学习一下 String…

Opensuse Tumbleweed快速部署K8S-1.28.2

** #查看你的网卡信息 nmcli device show#设置你的静态IP nmcli connection modify ens32 ipv4.method manual \ipv4.addresses 172.16.20.214/24 ipv4.gateway 172.16.20.1 \ipv4.dns 114.114.114.114#重启网卡生效 nmcli c down ens32 && nmcli c up ens32#添加DNS …

Java IDEA java.lang.IllegalStateException: Failed to introspect Class报错原因和解决办法

Java IDEA java.lang.IllegalStateException: Failed to introspect Class报错原因和解决办法 1. 报错如下&#xff1a;2. 解决 在maven右侧查看Dependencies冲突参考 1. 报错如下&#xff1a; 发现是因为 org.redisson:redisson.spring.boot.starter 3.10.6这个包引入不进来导…

如何使用 Canvas和HTML5中的SVG画一个矩形?

使用Canvas和SVG分别绘制矩形的方法如下&#xff1a; Canvas绘制矩形&#xff1a; <canvas id"canvas" width"200" height"200"></canvas><script>const canvas document.getElementById(canvas);const ctx canvas.getCon…