從今天開始專心閱讀幾本經典書籍,《編程珠璣》無疑是及其經典的一本。
讀後感主要包括問題,解決方案,總結及完成部分習題。
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待續。
外部文件排序之歸併算法待續。