【数据结构(邓俊辉)学习笔记】向量06——位图

文章目录

  • 0.概述
  • 1.结构
  • 2.实现
  • 3. 应用
    • 3.1 去重
    • 3.2 筛法

0.概述

位图(Bitmap)是一种特殊的序列结构,可用以动态地表示由一组(无符号)整数构成的集合。
在这里插入图片描述

  1. test() 判断k 是否存在集合S中。
  2. set() 将k 加入到集合S中。
  3. clear() 将k从集合S中移除。

若是32位,则长度U为 2 32 2^{32} 232,且其中每个元素的取值均为布尔型(初始值均为 false)。

1.结构

在这里插入图片描述
注意:bit的最小操作单位是8位,n+ 7是在做ceiling。

算法思想:

  • test算法:
    第一步:找bit所在基本单位区间,即以8个bit为单位的,k >> 3 即(k/8),即为入口。
    第二步:根据第一步找到的入口,计算offset值,k & 0x07 即(k%8),再生成掩码去操作single bit。
  • set算法 / clear算法:
    与test算法基本相同,将 & 改成 |= 或 &=~。
    在这里插入图片描述
    综上:
  • 就可在O(1)时间完成test set clear操作。
  • 位图向量所占的空间线性正比于集合的取值范。

2.实现

上述接口实现

class Bitmap { //位图Bitmap类
private:
   unsigned char* M;
   Rank N, _sz; //位图空间M[],N*sizeof(char)*8个比特中含_sz个有效位
protected:
   void init( Rank n )
      { M = new unsigned char[N = ( n + 7 ) / 8]; memset( M, 0, N ); _sz = 0; }
public:
   Bitmap( Rank n = 8 ) { init( n ); } //按指定容量创建位图(为测试暂时选用较小的默认值)
   Bitmap( char* file, Rank n = 8 ) { //按指定或默认规模,从指定文件中读取位图
      init( n );
      FILE* fp = fopen( file, "r" ); fread( M, sizeof( char ), N, fp ); fclose( fp );
      for ( Rank k = 0, _sz = 0; k < n; k++ ) _sz += test(k);
   }
   ~Bitmap() { delete[] M; M = NULL; _sz = 0; } //析构时释放位图空间

   Rank size() { return _sz; }
   void set   ( Rank k ) { expand( k ); _sz++; M[k >> 3] |=   ( 0x80 >> ( k & 0x07 ) ); }
   void clear ( Rank k ) { expand( k ); _sz--; M[k >> 3] &= ~ ( 0x80 >> ( k & 0x07 ) ); }
   bool test  ( Rank k ) { expand( k ); return M[k >> 3] &    ( 0x80 >> ( k & 0x07 ) ); }

   void dump( char* file ) //将位图整体导出至指定的文件,以便对此后的新位图批量初始化
   { FILE* fp = fopen( file, "w" ); fwrite( M, sizeof ( char ), N, fp ); fclose( fp ); }
   char* bits2string( Rank n ) { //将前n位转换为字符串——
      expand( n - 1 ); //此时可能被访问的最高位为bitmap[n - 1]
      char* s = new char[n + 1]; s[n] = '\0'; //字符串所占空间,由上层调用者负责释放
      for ( Rank i = 0; i < n; i++ ) s[i] = test( i ) ? '1' : '0';
      return s; //返回字符串位置
   }
   void expand( Rank k ) { //若被访问的Bitmap[k]已出界,则需扩容
      if ( k < 8 * N ) return; //仍在界内,无需扩容
      Rank oldN = N; unsigned char* oldM = M;
      init( 2 * k ); //与向量类似,加倍策略
      memcpy_s( M, N, oldM, oldN );
      delete[] oldM; //原数据转移至新空间
   }
};
  • 提供了一个dump()接口,可以将位图整体导出至指定的文件,以便对此后的新位图批量初始化。
  • 与可扩充向量一样,一旦即将发生溢出,这里将调用expand()接口扩容。可见,这里采用的也是“加倍”的扩容策略。

3. 应用

3.1 去重

在这里插入图片描述

  • 利用 Bitmap 类设计算法,在 O(n)时间内剔除 n 个 ASCII 字符中的重复字符,各字符仅保留一份

 1. 将非重复的ASCII字符视作一个集合,并将其组织为一个Bitmap结构——ASCII编码为k的字符,对应于其中第k个比特位。
 2. 初始时,该集合为空,Bitmap结构中的所有比特位均处于0状态。以下,只需在O(n)时间内遍历所有的输入字符,并对
ASCII编码为k的字符,通过set(k)接口将其加入集合。
 3. 请注意,这里使用的Bitmap结构只需128个比特位。因此,最后只需再花费O(128) = O(1)时间遍历一趟所有的比特位,
 并输出所有通过test()测试的比特位,即可完成字符集的去重。

3.2 筛法

  • 求素数
    算法思想:0和1自然不是,若2是,则认为2的倍数4,6,8均是,依次类推。最后留下来的则是素数。
    在这里插入图片描述
    实现思想:Bitmap B(n),记录待处理的数,0和1自然不是set掉,查看数i是否被set,若没有则以i为步长,set掉取余数。
    在这里插入图片描述
  • 利用 Bitmap 类设计算法,快速地计算不大二 10^8 的所有素数。
#include "../Bitmap/Bitmap.h" //引入Bitmap结极
/******************************************************************************************
* 筛法求素数
* 计算出不大于n的所有素数
* 不计内循环,外循环自身每次仅一次加法、两次判断,累计O(n)
* 内循环每趟迭代O(n/i)步,由素数定理至多n/ln(n)趟,累计耗时不过
* n/2 + n/3 + n/5 + n/7 + n/11 + ...
* < n/2 + n/3 + n/4 + n/6 + n/7 + ... + n/(n/ln(n))
* = O(n(ln(n/ln(n)) - 1))
* = O(nln(n) - nln(ln(n)) - 1)
* = O(nlog(n))
* 如下实现做了进一步优化,内循环从i * i而非i + i开始,迭代步数由O(n / i)降至O(max(1, n / i - i))
******************************************************************************************/
void Eratosthenes ( int n, char* file ) {
	Bitmap B ( n ); B.set ( 0 ); B.set ( 1 ); //0和1都不是素数
	for ( int i = 2; i < n; i++ ) //反复地,从下一
		if ( !B.test ( i ) ) //可认定的素数i起
			for ( int j = 2*i; j < n; j += i ) //以i为间隔
				B.set ( j ); //将下一个数标记为合数
	B.dump ( file ); //将所有整数的筛选标记统一存入指定文件,以便日后直接寻入
}

该算法可在O(nlogn)时间内计算出不超过n的所有素数。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

免费APP分发平台 - 一个指南和解析

数字化时代的APP分发平台 随着数字化进程的加速免费APP分发平台 - 一个指南和解析&#xff0c;移动应用&#xff08;APP&#xff09;市场正迅速扩大。在这个充满竞争的市场中免费APP分发平台 - 一个指南和解析&#xff0c;一个优秀的APP分发平台能够帮助开发者和商家更有效地触…

【matlab基础知识】(三)二维曲线绘制plot

x[-pi:0.0001:pi]; 选择较小步距 ysin(tan(x))-tan(sin(x));plot(x,y) 条件和函数值做一个点乘 x[-2:0.02:2];y1.1*sign(x).*(abs(x)>1.1)x.*(abs(x)<1.1);plot(x,y) 颜色&#xff0c;线形&#xff0c;曲线上的标志 由于0.01cosx波动太小&#xff0c;所以plotyy绘制多…

蓝桥杯练习系统(算法训练)ALGO-949 勇士和地雷阵

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 勇士们不小心进入了敌人的地雷阵&#xff08;用n行n列的矩阵表示&#xff0c;*表示某个位置埋有地雷&#xff0c;-表示某个…

可视化大屏C位图:智慧场馆/场所图

Hello&#xff0c;我是大千UI工场&#xff0c;本期可视化大屏的焦点图&#xff08;C位&#xff09;分享将场馆作为焦点图的情形&#xff0c;欢迎友友们关注、评论&#xff0c;如果有订单可私信。 智慧场馆是指通过物联网、大数据、人工智能等技术手段&#xff0c;将传统场馆与…

ctfshow crypto rsa部分题目简单题解

easyrsa1 下载点击打开附件 e 65537 n 1455925529734358105461406532259911790807347616464991065301847 c 69380371057914246192606760686152233225659503366319332065009 题目中给了e,n,c的值。 使用在线网址factordb.com 分解n得到p&#xff0c;q 编写脚本 import gm…

Java项目:基于SSM框架实现的在线医疗服务系统(ssm+B/S架构+源码+数据库+毕业论文+开题报告)

一、项目简介 本项目是一套基于SSM框架实现的在线医疗服务系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功能…

为什么 IP 地址通常以 192.168 开头?(精简版)

网络通讯的本质就是收发数据包。如果说收发数据包就跟收发快递一样。IP地址就类似于快递上填的收件地址和发件地址一样&#xff0c;路由器就充当快递员的角色&#xff0c;在这个纷繁复杂的网络世界里找到该由谁来接收这个数据包&#xff0c;所以说&#xff1a;IP地址就像快递里…

Java 获取 Outlook 邮箱的日历事件

Java 获取 Outlook 邮箱的日历事件 1.需求描述2.实现方案3.运行结果 IDE&#xff1a;IntelliJ IDEA 2022.3.3 JDK&#xff1a;1.8.0_351 Outlook&#xff1a;Microsoft Office 2016 1.需求描述 比如现在需要获取 Outlook 邮箱中四月的全部的会议安排&#xff0c;如下图所示 …

从零开始搭建Springboot项目脚手架1:新建项目

1、技术栈 SpringBoot 3.2.5&#xff1a; 2、 新建项目 使用SpringInitializr 选择Lombok、Configuration Processor、Spring Web&#xff0c;同时IDEA也要安装Lombok插件 删除多余的Maven目录、Maven文件&#xff0c;把HELP.md改成README.md。 当然前提是已经安装好Maven和配…

【JVM】Java工具(Arthas,APM,Java Agent,JMX)

Java工具 常见的Java工具有以下几类&#xff1a; 1、诊断类工具&#xff0c;如Arthas、VisualVM等。 2、开发类工具&#xff0c;如Idea、Eclipse。 3、APM应用性能监测工具&#xff0c;如Skywalking、Zipkin等。 4、热部署工具&#xff0c;如Jrebel等。 Arthas中 Java Ag…

[笔试训练](十二)

目录 034:删除公共字符串 035:两个链表的第一个公共节点 036:mari和shiny 034:删除公共字符串 删除公共字符_牛客题霸_牛客网 (nowcoder.com) 题解: 用哈希记录好第二个字符串中的字符&#xff0c;再遍历一遍第一个字符串&#xff0c;只将没有记录的字符加在结果字符串上。…

ASP.NET网络在线考试系统

摘 要 随着计算机技术的发展和互联网时代的到来&#xff0c;人们已经进入了信息时代&#xff0c;也有人称为数字化时代。数在数字化的网络环境下&#xff0c;学生希望得到个性化的满足&#xff0c;根据自己的情况进行学习&#xff0c;同时也希望能够得到科学的评价&#xff0c…

文件API及其操作

这里介绍两类文件操作、三个文件类。包括文件系统操作&#xff08;File类&#xff09;、文件内容操作&#xff08;操作字节流、操作字符流&#xff09; 1.文件类File 1.1.认识File类 &#xff08;1&#xff09;什么是File类呢&#xff1f;其实就是可以操作文件的一个类。通过…

STM32数字示波器+详细注释+上位机程序+硬件

目录 1、设计指标&#xff1a; 2、功能&#xff1a; 3、上位机的程序 ​4、测试的照片 5、PCB 6、模拟电路板 7、程序 资料下载地址&#xff1a;STM32数字示波器详细注释上位机程序硬件 1、设计指标&#xff1a; 主控: STM32…

【面试经典 150 | 字典树】添加与搜索单词 - 数据结构设计

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;字典树 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行回…

大功率双向直流电源的输出电压和电流

双向直流电源&#xff08;Bidirectional DC Power Supply&#xff09;是一种具有双向输出电能的直流电源。与传统的直流电源相比&#xff0c;双向直流电源在输出电能的同时&#xff0c;还具备一定的电流输入能力&#xff0c;从而使其应用范围更加广泛。大功率双向直流电源作为电…

【开发技巧 | 第二篇】IDEA新增作者信息、方法参数返回值

文章目录 2.IDEA新增作者信息、方法参数返回值2.1类新增作者信息2.2方法新增参数返回信息2.3测试2.3.1新建类2.3.2新建方法 2.IDEA新增作者信息、方法参数返回值 2.1类新增作者信息 打开IDEA的Settings&#xff0c;Editor->Code Style->File and Code Templates->Inc…

使用 ORPO 微调 Llama 3

原文地址&#xff1a;https://towardsdatascience.com/fine-tune-llama-3-with-orpo-56cfab2f9ada 更便宜、更快的统一微调技术 2024 年 4 月 19 日 ORPO 是一种新的令人兴奋的微调技术&#xff0c;它将传统的监督微调和偏好校准阶段合并为一个过程。这减少了训练所需的计算…

思科防火墙查如何查看现有ipsec隧道信息

环境&#xff1a; 思科ASA5555 问题描述&#xff1a; 思科防火墙查如何看现有ipsec隧道信息 解决方案&#xff1a; 1.进入特权模式&#xff1a; enable 查看isakmp信息 show crypto isakmp sa2.查看ipsec信息 show crypto ipsec sa上述命令将显示当前的ISAKMP安全关联…

设计模式之组合实体模式

在编程的奇幻森林里&#xff0c;树木与枝叶错综复杂&#xff0c;如何让代码世界井然有序&#xff1f;组合实体模式&#xff08;Composite Pattern&#xff09;就像一位高明的园艺师&#xff0c;它以一种巧妙的方式&#xff0c;将个体与整体统一管理&#xff0c;让无论是单个对象…