学习《编程珠玑》

     第一章是磁盘排序问题,面试的时候经常会遇到,百度实习生电话面试时就问了类似的题目,如果一次性能够读入内存,就利用bitmap,否则分多趟分别排序,主要基于归并思想。

    题目:1MB的空间里面对10,000,000个整数进行排序,并且每个数都小于10,000,000。

    很明显,若用32位int型保存每个数的话,一次只能读入250 000 个号码,若采用一个1千万位的字符串表示每个数,则只需在数字出现的位上置1,那么只需要10000000/(1024* 1024 * 8) = 1.25M。

    虽然位图法十分节省时间和空间,但是对于本题有三个限制:

    1、输入数据在相对较小的范围内;

    2、数据无重复;

    3、只有单一整数。

    鉴于STL已经封装好了bitset,所以实现如下:

int main()
{

	bitset<N> bit;
	int n;
	while(cin)
	{
		cin>>n;
		bit.set(n, 1);
	}
	for(int i = 0; i < N; i++)
	{
		if(bit.at(i) == 1)
			cout<<i<<endl;
	}
	return 0;
}

    C语言实现的方法比较晦涩。。。从网上copy来的:

#include <stdio.h>
#define MAX 10000000
#define SHIFT 5           
#define MASK 0x1F
#define DIGITS 32


int a[1+MAX/DIGITS];

void set(int n)                                //将逻辑位置为n的二进制位置为1 
{
    a[n>>SHIFT] |=(1<<(n&MASK));               //n>>SHIFT右移5位相当于除以32求算字节位置,n&MASK相当于对32取余即求位位置,
}                                                

void clear(int n)
{
    a[n>>SHIFT] &=(~(1<<(n&MASK)));           //将逻辑位置为n的二进制位置为0
}

int test(int n)
{
    return a[n>>SHIFT] & (1<<(n&MASK));        //测试逻辑位置为n的二进制位是否为1 
}

int main(int argc, char *argv[])
{
    int i,n;
    for(i=1;i<=MAX;i++)
    {
        clear(i);
    }    
    while(scanf("%d",&n)!=EOF)
    {
        set(n);
    }
    for(i=1;i<=MAX;i++)
    {
        if(test(i))
            printf("%d ",i);
    }
    return 0;
}

课后题目:

1、C语言中有qsort(),C++中有sort,STL中的set自动排序。

2、为了测试程序需要产生随机数

      就是将n个数利用随机数随机打乱,然后取k个,这里的重点是互不相同的k个数,所以可以利用set保证这一点:

   http://www.fookwood.com/archives/605

    今天太困,,,明天继续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值