编程珠玑 第一章 大数据排序

  方法总结:

 

补充:数据个数n,与内存大小的换算?

        1MB=2^10*8位

       2^10~10^3

      即10^7个整数占用的内存:

      10^7/(10^3)/ (10^3)/8约等于1.25MB

         或者:10^7/8/1024/1024≈1MB

     即内存大小=n/(10^3)/ (10^3)/8 MB

补充:10^m与2^n之间的关系?
          2^10~10^3
          所以:2^31=(2^10)*(2^10)*(2^10)*2
          约等于2*(10^3)*(10^3)*(10^3)=2*(10^30)

自己的思考:k趟排序中,每一趟也可以使用位图结构。

            如果自己的理解正确,那么数据只要是整数,不用限制数据的范围

             因为使用系统的MAX-每个数据就能实现位图排序。

问题:

  

 位图排序:一次文件读入内存,读出内存

  

第一阶段:关闭所有位,置为0;
第二阶段:读入每个整数,打开相应的位,置为1
第三阶段:检查每个位

伪代码:

for i=[0,n)
  bit[i]=0;
for each i in the input file
  bit[i]=1;
for i=[0,n)
   if bit[i]==1
      write i on the output file

代码:

 bitset<max+1> bit;                     //初始默认所有二进制位为0 
    
    while(scanf("%d",&n)!=EOF)
    {
        bit.set(n,1);                   //将第n位置1               
    }    
    for(i=0;i<=max+1;i++)
    {
        if(bit[i]==1)
            printf("%d ",i);
    }
    return 0;
}

k趟算法:需要多次读入文件    

时间复杂度:kn

空间复杂度:n/k

对k趟算法中的每一趟算法,满足条件的情况下,可以使用位图排序/快排/堆排序等等排序算法;

40个通道的算法:

   

其他不好的方法:

        磁盘的合并排序:运行时间太长, 几天

   

位图/多路归并排序的实现见:http://blog.csdn.net/v_JULY_v/article/details/6451990

习题

      1内存不紧缺,如何排序?

答:

1:快排/set容器

int intcomp(int *x,int *y)
{return *x-*y;
}
a[n]
qsort(a,n,sizeof(int),intcomp)

set容器:

  

2,使用位逻辑运算(与,或,移位)实现位向量?

答:

自己的理解:可以直接使用bitset,对相应位进行设置;

或者 set(i)实现为 a[i]|=1;

clr(i)实现为a[i]&=0;

test(i)实现为:if(a[i]&0x01)

3,实现位图排序,并测试时间?

答:

  

 

4,生成一个包含k个整数的文件,要求这些整数是唯一的,并且

在0到n-1之间随机出现,次序也是随机的?

答:

randint(l,u)返回l...u之间的一个随机整数。

for i=[0,n)

 x[i]=i;

for i=[0,k)

{

swap(i,randint(i,n-1));

print(x[i]);

}

自己的理解--还可以如下实现:

 fori=[1,n)

{

swap(i,rand ()%(i+1));

}

然后仅打印前k个整数

 

5,只有1MB的内存,但是需要编写的代码有1.25MB,推荐什么算法?

答:

  

重点   6,如果每个整数最多出现10次,而不是每一个整数至多出现1次,如何改进程序?

答:如果最多出现10次,可以使用半个字节4位统计它出现的次数。

类推:若最多出现20次,使用可以使用5位,统计出现的次数;

若最多出现n次,使用对logn上取整的位数,统计出现的次数;


根据位图法演变解决以下QQ面试题目:作者:Nick Ye(yjf512)出处:(http://www.cnblogs.com/yjf512/

http://www.cnblogs.com/yjf512/archive/2010/11/04/1868899.html

40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,

如何快速判断这个数是否在那40亿个数当中。

unsign int范围为0~2^32-1(4294967295≈5*10^9)使用位图hash对应5*10^9/8/10^3/10^3 = 625MB.

1.       我们使用625M的字符串。每一位设置为0.

2.      40亿个unsign int遍历一遍。使用位图法将字符串中的对应位转化为1

读取再给一个数i”查看bit[i]是否为11则有存在,0则不存在。










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多则惑少则明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值