关于位向量的笔记

在《编程珠玑》中提到一个用位向量解决排序的问题,其具体的要求如下:

输入:一个包含最多n个整数的文件,每个整数都小于n,且无重复

输出:按升序排列的输入整数的列表

约束:最多有(大约)1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10秒就不需要进一步优化了。

基本的思路是这样的:用n个位表示0-n之间的整数,其中位的状态分为0和1两种,0表示这个整数没有出现,1表示出现了。输出时遍历每一位,状态为1则输出该位的序号,即为整数值。不能用一个变量表示一个位,因为这样对于空间的浪费是很严重的,但是可以分配一个int,再将多个int组成一个数组,得到int数组。对于这个数组内的int进行位操作。

因此位向量的实现方法大致的思路是:多个位组成一个基本数据类型,多个基本数据类型组成数组。对于上面这个问题只要找出表示整数的未即可。方法如下:


 1 //整数的位数,假设为32
2 #define BitPerWord 32;
3 //定义移位的长度,2的5次方为32
4 #define Shift 5
5 //定义取模的掩码
6 #define Mask 0x1F
7 //定义整数的最大值
8 #define N 100000
9
10 //数组饿大小
11 int intArray[(N-1)/max + 1]
12 /*
13 *根据参数i,设置对应的标志位的值
14 *i>>SHIFT,i右移5位,相当于i/32
15 *i & MASK,i和11111做与运算,得到i%32
16 *1<<(i & MASK),1左移(i%32)位,将结果与a[i>>SHIFT]做或运算
17 *即可设置整数i对应的标志位为1
18 */

举个例子:

所以只需定义一个长度为107/32的整型数组即可提供所需的二进制位,整数数组记为A。
从输入文件中读入一个整数,将这个整数整除32,得到的结果即是表示该数存在的二进制位记录在数组的哪个下标的整数中,
比如111,用111整除32得3,即代表该数存在的二进制位在数组下标为3的数,即A[3]中。
将读入的数模32,得到的数即为代表该数的标志位在A[3]中的位置,比如111模32结果为15,
则将A[3]的第15位置为1,即A[3]现在为00000000000000000100000000000000,即为32768
如此即可使用整型数组模拟位集合,比如读入的第二个数为127,127整除32为3,模32为31,则A[3]为10000000000000000100000000000000

有3种相应的位操作,分别为设置为0,设置为1,读取当前值。以下是具体实现:

//与位移之后的1做或,使得该位置的该位为1
void set(int i){
a[i>>Shift] |= (1<<(i&Mask));
}
void clr(int i){a[i>>Shift] &= ~(1<<(i&Mask));}
void test(int i){ return a[i>>Shift] & (1<<(i&Mask));}

因此对于上述问题的揭发就是一次读入文件,将出现过的数字所表示的位设为1,之后在遍历所有位,即1-N,将位为1的值输出即是升序排列。

关于位向量的笔记

时间: 2024-09-30 11:09:00

关于位向量的笔记的相关文章

【读书笔记】《编程珠玑》第一章之位向量&amp;位图

此书的叙述模式是借由一个具体问题来引出的一系列算法,数据结构等等方面的技巧性策略.共分三篇,基础,性能,应用.每篇涵盖数章,章内案例都非常切实棘手,解说也生动有趣. 自个呢也是头一次接触编程技巧类的书籍,而且算法数据结构方面的知识储备实在是薄弱,这么看来,纯粹找虐啊orz.今此行为,歇业养伤,实属无聊.也可说是自打毕业后,看书如打仗,自视身处"安安稳稳的和平年代",闲来了也就闲着,忧患意识甚少,有也退退缩缩.话说回来,这本书不像CLRS那种难打的硬仗(现在想想都脑仁疼啊),<Pr

位向量 补码与无符号 加法与乘法 CSAPP学习笔记

计算机中用位来表示整数,一种方式只能表示非负数,一种可以表示有符号数. 无符号数编码: 补码编码: 由上面的定义可以知道补码与无符号之间的对应关系(见下式),最高位为0时,补码与无符号表示是一样的,而最高位为1时,举个例子,补码表示的-1对应于无符号数的4294967295(这里指的是32位数) . 在整数运算之前必须先了解 整数的扩展和截断 扩展分为零扩展和符号扩展,零扩展是简单的在表示的开头添加0,适用于无符号数的扩展.而符号扩展在表示中添加最高有效位值的副本,适用于补码的扩展.比如4位的1

【转】Java基础笔记 – 枚举类型的使用介绍和静态导入--不错

原文网址:http://www.itzhai.com/java-based-notes-introduction-and-use-of-an-enumeration-type-static-import.html#1.2.values方法的使用: Java基础笔记 – 枚举类型的使用介绍和静态导入 本文由arthinking发表于4年前 | Java基础 | 暂无评论 |  被围观 8,332 views+ 1.枚举(Enum):1.1.枚举类型中的两个静态方法:1.2.values方法的使用:

java笔记--枚举总结与详解

由于工作原因,已经有两礼拜没有更新博客了,好不容易完成了工作项目,终于又可以在博客园上愉快的玩耍了. 嗯,今天下午梳理了一下关于java枚举的笔记,比较长,不过还是觉得挺厚实的,哈哈,有出入的地方,欢迎朋友们指出来,一起学习,共同进步!! 一.枚举简介:     为什么要用枚举:     枚举是Java1.5出来之后新增的类型,它可以用来定义一组取值范围固定的的变量.     在枚举没有出来之前,要定义这样的变量,往往是通过定义一个接口,将不同的变量     使用不同的整数赋值.但是这样的却有着

Latent Semantic Analysis (LSA) 模型 学习笔记

Latent Semantic Analysis (LSA) 模型 学习笔记 Latent Semantic Analysis 模型,隐性语义分析,也就是我们常说的LSA模型.后面还有他的兄弟PLSA和LDA模型,这个我们后面再说.这几个都是NLP中比较经典的模型!学习这个模型,主要总结到了三个方面:LSA模型可以应用在哪儿?LSA的理论部分,以及LSA的优缺点分析. 1. LSA的应用 LSA可以在VSM中降低样本的维度,并且可以从文本中发现隐含的语义维度. 在VSM中,文档被表示成由特征词出

【安全牛学习笔记】

弱点扫描 ╋━━━━━━━━━━━━━━━━━━━━╋ ┃发现弱点                                ┃ ┃发现漏洞                                ┃ ┃  基于端口五福扫描结果版本信息(速度慢)┃ ┃  搜索已公开的漏洞数据库(数量大)      ┃ ┃  使用弱点扫描器实现漏洞管理            ┃ ╋━━━━━━━━━━━━━━━━━━━━╋ [email protected]:~# searchsploit Usage:

51CTO持续更新《通哥的运维笔记》

<通哥的运维笔记>将持续在51CTO网站更新,希望大家多多关注.互相学习,后期,我将会退出<通哥的运维笔记>系列视频教程,希望带给大家最大的收获,帮助大家更好的学习.进步.<通哥的运维笔记>主要从linux系统管理.虚拟化.cloudstack云平台以及网络管理之CCNA.CCNP.CCIE,等等方面深入讲解.

WPF笔记整理 - Bitmap和BitmapImage

项目中有图片处理的逻辑,因此要用到Bitmap.而WPF加载的一般都是BitmapImage.这里就需要将BitmapImage转成Bitmap 1. 图片的路径要用这样的,假设图片在project下的Images目录,文件名XXImage.png. pack://application:,,,/xxx;component/Images/XXImage.png 2. 代码: Bitmap bmp = null; var image = new BitmapImage(new Uri(this.X

java String 类 基础笔记

字符串是一个特殊的对象. 字符串一旦初始化就不可以被改变. String s = "abc";//存放于字符串常量池,产生1个对象 String s1=new String("abc");//堆内存中new创建了一个String对象,产生2个对象 String类中的equals比较字符串中的内容. 常用方法: 一:获取 1.获取字符串中字符的个数(长度):length();方法. 2.根据位置获取字符:charAt(int index); 3.根据字符获取在字符串中