《编程珠玑》(第二版)第一章习题2(用位运算实现位向量)

原创 2016年05月30日 13:56:55

《编程珠玑》第一章提出了一个排序问题,可以用位图或位向量来表示。如可用一个20位长的字符串来表示一个所有元素都小于20的简单非负整数集合,如集合{1,2,3,5,8,13}可以表示为:

0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0

代表集合中数字的位都置为1,其他所有的位都置为0。

若给定表示文件中整数集合的位图数据结构,则可以分三个自然阶段来编写程序。第一阶段将所有的位都置为0,从而将结合初始化为空。第二阶段读入文件中的每个整数来建立结合,将每个对应的位都置为1。第三个阶段检验每一位,如果该位为1,就输出对应的整数。伪代码如下:

/*phase 1: initialize set to empty*/
for i=[0,n)
    bit[i]=0
/*phase 2: insert present elements into the set*/
for each i in the input file
     bit[i]=1
/*phase 3: write sorted output*/
for i=[0,n)
     if bit[i]==1
       write i on the output dile
一个字符占一个字节,也就是4个位,但是我们只需要一个位来表示,这样还是会造成浪费。可以用整数数组来模拟位数组。下面是习题2的参考答案,使用位逻辑运算来实现位向量图。

// bitmap.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<iostream>

#define BITSPERWORD 32 //表示一个整型含有32位
#define SHIFT 5
#define MASK 0x1F  //0000000000000000 0000000000011111
#define N 10000000  //表示1000万个整数

using namespace std;

int a[1 + N / BITSPERWORD];//使用整型数组模拟1000万个位的数组

void set(int i){
	//i>>SHIFT相当于i/32,表示该数由第几个整数表示,i&MASK相当于i%32,表示该数在整数中的第几个位
	//1<<(i&MASK)就将该位设为1
	a[i >> SHIFT] |= (1 << (i&MASK)); 
}
void clr(int i)
{
	a[i >> SHIFT] &= ~(1 << (i&MASK));
}
int test(int i)
{
	return a[i >> SHIFT] & (1 << (i&MASK));
}

int _tmain(int argc, _TCHAR* argv[])
{
	
	int i;
	for (i = 0; i < N; ++i)
		clr(i);
	cout << "输入数据:" << endl;
	while (cin >> i)
		set(i);
	cout << "输出结果:" << endl;
	for (i = 0; i < N; ++i)
	{
		if (test(i))
			cout << i <<" " ;
	}
	cout << endl;
	return 0;
}

实验结果如下:




后记:

输入数据限制在相对较小的范围内,数据没有重复的情况下,可以考虑使用位图来存储数据实现排序。


参考:

http://blog.chinaunix.net/uid-26548237-id-3759520.html

编程珠玑 如何使用位逻辑运算(例如与、或、移位)来实现位向量

位向量的用处,自己感觉有两个: 1.排序。但是限制条件太多 2.做标记数组。好处是:大大的减少了空间 #include using namespace std; /* 如何使用位逻辑运算(例...

编程珠玑:通过位逻辑运算实现位向量

位向量基本思想:位向量是一种简单高效的数据结构,该结构一般可以用来描述一个有限定义域内的稠密集合,其中该集合内的数据最多出现一次且没有其他任何数据与之关联(通常把数据的其他关联忽略掉,只关心该集合内的...

编程珠玑位逻辑运算实现位向量

看编程珠玑时,看到位逻辑运算实现位向量,思考了一些时间,做一些注释。/*位图数据结构:该数据结构描述了一个有限定义域内的稠密集合,其中每个元素最多出现一次并且没有其他任何数据结构与该元素相关联*/ #...

编程珠玑--如何使用位逻辑运算(例如不、或、移位)来实现位向量

首先说明一下,假设使用的是8bit的数据类型(32bit的不好画),数据是怎么排列的: 然后去理解下面的代码: #define BITSPERWORD 32 //表示一个整型含...

编程珠玑第二版第四章习题(Java)

>1 初始限定 上下限范围,下限不会变小,上限不会变大,保证不会越界。2 二分法改进,第一次找到指定数字后记录该位置,姑且叫他location,之后锲而不舍的向前二分寻找,因为找第一次出现,所以肯定不...

编程珠玑第二版第五章习题(Java)

1 (此段内容来自原书,在此向原作者表示感谢)When I write large programs, I use long names (ten or twenty characters) for ...

[编程珠玑]-第一章:位图/位向量排序

源于编程珠玑-第二版 问题描述:(第一章1.2节) 输入:一个最多包含n个正整数的文件,每个数都小于n, n=10^7,  输入文件中整数不重复,且无其他数据与该整数相关联。 输出:按升序排列...
  • only06
  • only06
  • 2017年07月15日 21:44
  • 75

编程珠玑第二版第六章习题(Java)

这一章的程序性能分析通常在数据结构第一张就会讲到。 3 写个程序测试一下 public class TimeTest { public static void main(String[] args)...

编程珠玑(第二版)读书笔记第一章

前言:           这本书也是看了别人的

《编程珠玑》之位运算知识

《编程珠玑》第二章的问题A,给40亿个不重复的unsigned int的整数,没有排过序,然后再给一个数,如果快速判断这个数是否在那40亿个数当中。不考虑内存的情况下,如何解决。 问题先放这里,我们先...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《编程珠玑》(第二版)第一章习题2(用位运算实现位向量)
举报原因:
原因补充:

(最多只允许输入30个字)