原文中的問題:
如何在1mb的空間裡面對一千萬個整數進行排序?並且每個數都小於1千萬。實際上這個需要1.25mb的記憶體空間。
1mb總共有838,8608。所以估計也可以在1mb左右的空間裡面進行排序了。
#include #include #define bitsperword 32
#define shift 5
#define mask 0x1f
#define n 10000000
int a[1 + n/bitsperword];
void set(int i)
void clr(int i)
int test(int i)
int main()
課後的題目:
1、使用庫來進行排序
#include #include #define ms 1025
int a[ms];
int cmp(const void *a, const void *b)
int main(void)
return 0;
}
2、使用位運算
void set(int i)
void clr(int i)
int test(int i)
3、比較位圖排序與系統排序
位圖排序是最快的,針對這個問題而言,qsort比stl sort速度快。
4、隨機生成[0, n)之間不重複的隨機數
for (i = 0; i < n; ++i)
a[i] = i;
for (i = 0; i < n; ++i)
5、如果1mb是嚴格控制的空間,如果資料有1.25mb的bit數目。那麼應該是需要讀取2次。
k = 需要跑幾趟直接用需要排序的資料量/記憶體空間bit數,往上取整則可。
時間開銷 = kn
空間開銷 n/k
注意的是,每次在掃瞄的時候,取資料的範圍是不一樣的。
6、如果每個資料出現最多10次,那麼需要4個bit位來燒錄乙個數。這時儲存空間減小至原來的1/4。
那麼如果一定要按照bitmap的方式來進行處理,則需要利用5題中的結論。
7、問題:[r. weil]本書1.4節中描述的程式存在一些缺陷。首先是假定在輸入中沒有出現兩次的整數。如果某個數出現超過一次的話,會發生什麼?在這種情況下,如何修改程式來呼叫錯誤處理函式?當輸入整數小於零或大於等於n時,又會發生什麼?如果某個輸入不是數值又如何?在這些情況下,程式該如何處理?程式還應該包含哪些明智的檢查?描述一些用以測試程式的小型資料集合,並說明如何正確處理上述以及其他的不良情況。
如果某個數出現超過一次的話,會發生什麼?
會被忽略掉, 因為原來的程式本身就是用來處理只出現一次的情況的。
在這種情況下,如何修改程式來呼叫錯誤處理函式?
while (scanf("%d", &i) != eof)
if(test(i)) call_error_fun();
else set(i);
當輸入整數小於零或大於等於n時,又會發生什麼?
會出現訪問越界的情況。-1訪問時,會訪問a[-1]的31個bit位。
如果某個輸入不是數值又如何?在這些情況下,程式該如何處理?
輸入可能是浮點數,或是字元什麼的~~
可以先讀入字串,再用atoi轉換成為整形數,如果失敗,則進行出錯處理。
程式還應該包含哪些明智的檢查?
8、免費**號碼至少有800,878,888等,那麼如何檢視乙個號碼是否是免費號碼。?
第一種方案:如果是一千萬個**號碼都有可能成為免費號碼,那麼至需要1.25mb * (免費號碼字首個數)。
第二種方案:省空間,多次掃瞄檔案:
1、首先掃瞄整個檔案,看有哪個免費號碼字首。以及每個免費號碼字首下的號碼個數。
2、設定區間對映表:比如800字首有125個免費號碼,找到最大的數,與最小的數,差值做為bit長度。
第三種方案:建立索引的方式來進行處理。以最後7位為索引,後面800,878什麼的,為值。如果不是免費號碼,應該是不用加入到這個hash表中。
9、避免初始化問題
做法是:使用兩個等長的輔助陣列,比如要把a[n]初始化,那麼在第一次訪問時:
b[i] = top;
c[b[i]] = i;
++top;
給出示例**
#include#include#include#define ms 100
int a[ms];
int b[ms];
int c[ms];
int top;
//判斷是否被初始化過。
bool is_init(int i)
int main(void)
int v = i + rand()%(ms - i + 1);
int t = a[i]; a[i] = a[v]; a[v] = t;
v = i + rand()%(ms - i + 1);
t = b[i]; b[i] = b[v]; b[v] = t;
v = i + rand()%(ms - i + 1);
t = c[i]; c[i] = c[v] ; c[v] = t;
} for (int i = 0; i < ms; ++i) }
for (int i = 0; i < ms; ++i) }
return 0;
}
10、由於唯一性,採用hash啊。 程式設計珠璣第一章
下午看完程式設計珠璣第一章,感覺很不錯!如作者所說 閱讀本書乙個提示,不要太快,一次閱讀一章。集中精力思考,解答課後習題。寫總結就是在剛弄懂的時候,這時候是最恰當的時候,最容易接受。題目要求 乙個最多含有1000萬個整數的檔案,整數沒有重複,請輸出公升序排列。約束 最多1m記憶體,時間10s。題目很...
《程式設計珠璣》第一章筆記
文章從乙個實際的問題開始 乙個 系統,7位數的 號碼,用1mb的記憶體空間將這些 號碼排序。分析 如果將這些 號碼看成int型別的整數,將其讀入記憶體中進行排序,int型別4個位元組,最多有10000000個 號碼,則需要40mb的記憶體空間,遠遠超出題目的要求,但是這10000000個資料有他們的...
程式設計珠璣 第一章解析
問題 輸入 乙個最多包含n個正整數的檔案,每個數都小於n n 1000w 如果在輸入檔案中有任何整數重複出現就是致命錯誤。沒有其他資料與該整數相關聯。輸出 按公升序排列的輸入整數的列表。約束 最多有 大約 1 mb的記憶體空間可用,有充足的磁碟儲存空間可用。執行時間最多幾分鐘,執行時間為10秒就不需...