• Careercup


    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
    ", 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.
    ");
    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
    ", 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 }
  • 相关阅读:
    Java基础知识➣面向对象(八)
    Linux(CentOS7)安装Tomcat
    Java基础知识➣发送Emai和访问MySQL数据库(七)
    Java基础知识➣网络Socket(六)
    JS 的点点滴滴
    git 快速入门(二)
    zxing 生成二维码
    js生成二维码
    Markdown简介
    java常用string inputStream转换
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3722708.html
Copyright © 2020-2023  润新知