2014-05-12 07:44
原题:
Given an array having 16000 unique integers, each lying within the range 1<x<20000, how do u sort it. U can load only 1000 numbers at a time in memory.
题目:一个数组里有16000个不重复的整数,所有元素都在1和20000之间。如果你一次至多能在内存里放1000个整数,你要如何排序整个数组?
解法1:这个题目表述是不是有问题?数组本身就是内存的数据吧?内存装不下还叫数组?既然所有元素都是不重复的,就可以用位向量了。用位向量标记,就可以通过一次扫描来排序所有元素了。如果按照一个整数4字节的话,1000个整数有4000字节,总共32000个位,是足够覆盖数据范围的。如果按照16位整数来算,这个算法就不可行了。《编程珠玑》和《Cracking the Coding Interview》上都有类似的题目。内存限制是任何时候都要考虑的实际问题。如果资源总是无限的,这个世界也就没问题需要解决了。
代码:
1 // http://www.careercup.com/question?id=23123665 2 // all numbers are unique. 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 int main() 8 { 9 const int MAXN = 20000; 10 FILE *fin, *fout; 11 unsigned bit[MAXN >> 5]; 12 int i; 13 14 memset(bit, 0, MAXN / 8); 15 16 fin = fopen("in.txt", "r"); 17 while (!feof(fin)) { 18 fscanf(fin, "%u", &i); 19 bit[i >> 5] |= (1 << (i & 31)); 20 } 21 fclose(fin); 22 fin = nullptr; 23 24 fout = fopen("out.txt", "w"); 25 for (i = 0; i < MAXN; ++i) { 26 if (bit[i >> 5] & (1 << (i & 31))) { 27 fprintf(fout, "%u\n", i); 28 } 29 } 30 fclose(fout); 31 fout = nullptr; 32 33 return 0; 34 }
解法2:如果元素存在重复的话,就不能用位向量了。可以用数组来分段统计每个数据范围元素出现的个数,这样能通过多次扫描达到排序的效果。
代码:
1 // http://www.careercup.com/question?id=23123665 2 // may contain duplicates. 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 using namespace std; 7 8 int main() 9 { 10 const int MAXN = 20000; 11 const int n = 1000; 12 FILE *fin, *fout; 13 int count[n]; 14 int i, j; 15 int offset; 16 17 fin = fopen("in.txt", "r"); 18 fout = fopen("out.txt", "w"); 19 if (fin == nullptr || fout == nullptr) { 20 printf("File doesn't exist.\n"); 21 exit(1); 22 } 23 24 offset = 0; 25 while (offset < MAXN) { 26 memset(count, 0, n * sizeof(int)); 27 28 fseek(fin, 0, SEEK_SET); 29 while (!feof(fin)) { 30 fscanf(fin, "%d", &i); 31 if (i >= offset && i < offset + n) { 32 ++count[i - offset]; 33 } 34 } 35 36 for (i = 0; i < n; ++i) { 37 for (j = 0; j < count[i]; ++j) { 38 fprintf(fout, "%d\n", i + offset); 39 } 40 } 41 42 offset += n; 43 } 44 fclose(fin); 45 fin = nullptr; 46 fclose(fout); 47 fout = nullptr; 48 49 return 0; 50 }