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

《编程珠玑》第一章提出了一个排序问题,可以用位图或位向量来表示。如可用一个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

本书是计算机科学方面的经典名著。书的内容围绕程序设计人员面对的一系列实际问题展开。作者Jon Bentley 以其独有的洞察力和创造力,引导读者理解这些问题并学会解决方法,而这些正是程序员实际编程生涯中至关重要的。本书的特色是通过一些精心设计的有趣而又颇具指导意义的程序,对实用程序设计技巧及基本设计原则进行了透彻而睿智的描述,为复杂的编程问题提供了清晰而完备的解决思路。本书对各个层次的程序员都具有很高的阅读价值。. 多年以来,当程序员们推选出最心爱的计算机图书时,《编程珠玑》总是列前列。正如自然界里珍珠出自细沙对牡蛎的磨砺,计算机科学大师Jon Bentley以其独有的洞察力和创造力,从磨砺程序员的实际问题中凝结出一篇篇不朽的编程珠玑”,成为世界计算机界名刊《ACM通讯》历史上最受欢迎的专栏,最终结集为两部不朽的计算机科学经典名著,影响和激励着一代又一代程序员和计算机科学工作者。本书为第一卷,主要讨论计算机科学中最本质的问题:如何正确选择和高效地实现算法。.. 在书中,作者选取许多具有典型意义的复杂编程和算法问题,生动描绘了历史上众大师们在探索解决方案中发生的轶事、走过的弯路和不断精益求精的历程,引导读者像真正的程序员和软件工程师那样富于创新性地思考,并透彻阐述和总结了许多独特而精妙的设计原则、思考和解决问题的方法以及实用程序设计技巧。解决方案的代码均以C/C++语言编写,不仅有趣,而且有很大的实战示范意义。每章后所附习题极具挑战性和启发性,书末给出了简洁的解答。...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值