编程珠玑_第一章_ 开篇

本文介绍了如何使用位图排序处理不超过10,000,000个正整数的序列,探讨了在内存有限(1MB)的情况下如何通过遍历和优化策略进行排序。内容涉及位图排序的原理、设置与判断位图位置的方法、优化方案以及处理数据重复和电话号码排序的问题。" 133534618,19671764,Windows Subsystem for Android:微软开启Windows上的Android应用开发新时代,"['microsoft', 'android', '编程', 'Windows开发', '应用程序开发']

问题:

输入:给出至多10,000,000个正整数的序列

特征:每个数都小于10,000,000、数据不重复 且 数据之间不存在关联关系(相互独立)

输出:增序输出序列

约束:内存容量1MB,磁盘空间充足,运行时间至多几分钟,10是最适宜的时间

分析:我们需要10,000,000个数表示10,000,000个位。1MB的包含8*1024*1024个位

则,所需要的内存容量为:10,000,000/(8*1024*1024) = 1.20MB

这里和要求的差不多,我们可以使用位图排序,之后再进行优化,使之在1MB内存上运行

思路:

/*第一步,初始化这个比特位集合中的所有位为0*/
for i = [0,  10,000,000)    
	bit[i] = 0

/*第二步,读入待排序的正整数*/
for each i in the input file    
	bit[i] = 1

/*第三步,输出排序结果*/
for i = [0, 10,000,000)    
	if bit[i] == 1       
		write i on the output file

程序

使用字节存储位向量

#include <iostream>
using namespace std;

const int BITRERBYTE = 8;//位向量使用字节存储存储
const int SHIFT = 3;     //右移3位,相当于除去8
const int MASK = 0x7;    //16进制下的7
const int MAXNUM = 10000000;//最大的数为1千万

const int NUMCOUNT = 5;//实际待排序的数个数
unsigned char bit[MAXNUM/BITRERBYTE + 1];//位向量

/*置0*/
void InitBit(int i)
{
	bit[i>>SHIFT] &= ~(1 << (i&MASK));
}

/*置1*/
void SetBit(int i)
{
	bit[i>>SHIFT] |= (1 << (i&MASK)); 
}

/*检查是否1*/
int TestBit(int i)
{
	return bit[i>>SHIFT] & (1 << (i&MASK));
}

int main()
{
	int arr[NUMCOUNT] = {3,2,5,4,9};
	//关闭所有位
	memset(bit,0,sizeof(bit));
	//读入待排序的整数
	for (int i = 0;i < NUMCOUNT;i++)
	{
		SetBit(arr[i]);
	}
	//输出数据
	for (int i = 0;i < MAXNUM;i++)
	{
		if (TestBit(i))
		{
			cout<<i<<" ";
		}
	}
	cout<<endl;
	system("pause");
	return 1;
}

使用整形存储位向量

#include <iostream>
using namespace std;

const int BITPERWORD = 32;//位容器使用整形数据存储
const int SHIFT = 5;      //右移5位,相当于除去32
const int MASK = 0x1F;    //16进制下的31
const int MAXNUM = 10000000;//最大的数为1千万

const int NUMCOUNT = 5;//实际待排序的数个数

int bit[MAXNUM/BITPERWORD+ 1];//位向量

/*置0*/
void InitBit(int i)
{
	bit[i>>SHIFT] &a
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值