Careercup - Microsoft面试题 - 23123665

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 }

 

你可能感兴趣的:(Microsoft)