从今天开始专心阅读几本经典书籍,《编程珠玑》无疑是及其经典的一本。
读后感主要包括问题,解决方案,总结及完成部分习题。
Cracking the Oyster主要是一个排序的问题。
不超过10,000,000(N个)个不同7位数的排序问题。
初看就是一个磁盘外部排序的问题,通过归并排序或者调用系统函数即可。
通过和该程序员进行更为深入的交流对程序的需求有了细致的理解发现第一印象并不适合该问题。
通过引入bitmap在时间和空间上都得到了很高的效率。
时间O(N),空间O(N)。
类似于计数排序。
思想:
1.初始化bitmap
2.读数据,置1
3.顺序扫描bitmap,写数据
小结:
首先:不要对问题轻易下结论,很多问题都有比较特殊的环境,通过对问题的深入了解有助于高效的解决问题。
其次:复杂、困难的问题往往也有简单,令人意想不到的解决方法,简单的往往是美的,健壮的,易维护的,安全的。
摘录一句很经典的话:
A designer knows he has arrived at perfection not when there is no longer anything to add, but when there is no longer anything to take away.
部分习题:
1.如果主存没有限制,通过读入数组,调用sort即可。
2.如何通过位运算(&,|,~)实现bitmap
位运算主要操作:清空,赋值,读值(看是否为1)。
计3个函数clr(i),set(i),isExist(i)。
假设通过int(假定4位)模拟bitmap。
则每个int可以表示32个bit
附代码如下:
- #include <stdio.h>
- #define MASK 0x1f
- #define SHIFT 5
- #define MAXN 10000000
- int bit[1+MAXN/(1<<SHIFT)] ; //int模拟bitmap
- int array[MAXN] ; //随机模拟待排序数组
- void clr(int i)
- {
- bit[i>>SHIFT] &= ~( 1 << ( i & MASK ) ) ;
- }
- void set(int i)
- {
- bit[i>>SHIFT] |= 1 << ( i & MASK ) ;
- }
- bool isExist(int i)
- {
- return bit[i>>SHIFT] & ( 1 << ( i & MASK ) ) ;
- }
- void main()
- {
- int i , j , n ;
- while (~scanf("%d",&n))
- {
- //生成随机数组
- srand(0);
- for( i = 0 ; i < n ; i++)
- {
- while(1)
- {
- j = rand() % (n+100) ; //假定随机值 < n+100
- if(!isExist(j))
- {
- array[i] = j ;
- break ;
- }
- }
- }
- puts("随机生成的数组:");
- for( i = 0 ; i < n ; i++) printf("%d ",array[i]);
- puts("");
- //清空
- for( i = 0 ; i < n ; i++) clr(array[i]);
- //赋值
- for( i = 0 ; i < n ; i++) set(array[i]) ;
- //读值
- puts("bitmap排序后的数组:");
- for( i = 0 ; i < n + 100 ; i++) if(isExist(i)) printf("%d ",i);
- puts("");
- }
- }
3.测量几种不同的排序所消耗的时间。通过clock函数(c++)即可。
4.随机数生成问题。我想通过函数迭代实现可以实现吧,没看相关内容。
5.如果不能申请到1.25M,只有1M怎么办?
2次即可。对于多次的,添加一个offset即可。
6-12待续。
外部文件排序之归并算法待续。