A题是这样子的:

  给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数(在文件中至少缺失一个这样的数据——为什么?)。在具有足够内存的情况下,如何解决该问题?如果有几个外部的“临时”文件可用,但是仅有几个字节的内存,又该如何解决该问题?

  

  因为2^32>40亿,所以,在文件中至少会缺少一个这样的数据。在有足够内存的情况下,我们可以使用上一章提到的位图数据结构来解决该问题。但利用位图数据结构来解决该问题需要利用到的内存为:40亿/8/1024/1024=476MB,所以当内存不足时是不能够用这种方法的。

  前面一篇博文提到了可以用数列求和方法来求得缺失的数。但就是这种方法有一个要求就是,任一个数与其前一个数的差值是一个定值,即要求该数列是一个等差数列。所以,如果我们能够确定,这个需要找出缺失的数的顺序文件里边的数是一个等差数列,那我们就可以利用该方法简单求出缺失的数了,而且占用内存极少,效率当然也就更高。

  作者对该问题的解决方法是利用“二分搜索”的方法。具体如下:

  算法的第一趟(最多)读取40亿个输入整数,并把起始位为0的整数写入一个顺序文件,把起始位为1的整数写入另一个顺序文件。如下图所示。

  “《编程珠玑》(第2版)第2章”:A题(二分搜索)

  这两个文件中,有一个文件最多包含20亿个整数,我们接下来将该文件用作当前输入并重复探测过程,但这次探测的是第2个位。如果原始的输入文件中包含n个元素,那么第1趟将读取n个整数,第2趟最多读取n/2个整数,第3趟最多读取n/4个整数,依此类推,所以总的运行时间正比于n。通过排序文件并扫描,我们也能够找到缺失整数,但是这样做会导致运行时间正比于nlogn。

  下边我们就来看看,用“二分搜索”怎么解决这个问题:

  1. 文件读写

  首先我们来看怎么进行文件的读写。有一篇博文总结的很不错,值得参考。贴出具体代码如下:

 1 #include <iostream>
 2 #include <fstream>
 3 #include <string>
 4 #include <sstream>
 5 #include <math.h>
 6 using namespace std;
 7 
 8 int main()
 9 {
10     // *************************** Write File *************************** // 
11     // Open file
12     ofstream wfile("file.txt", ios::out);
13     if (!wfile)
14     {
15         cout << "The file can not be opened!" << endl;
16         exit(1);
17     }
18 
19     for (int i = 0; i < pow(2, 16); i++)
20     {
21         stringstream ss;
22         ss << i;
23         string str = ss.str();
24         wfile << str;
25         wfile << endl;
26     }
27 
28     // Close the file
29     wfile.close();
30 
31     // *************************** Read File *************************** //
32     // Open file
33     ifstream rfile("file.txt", ios::in);
34     if (!rfile)
35     {
36         cout << "The file can not be opened!" << endl;
37         exit(1);
38     }
39     
40     string line;
41     int num;
42     while (getline(rfile, line))
43     {
44         // cout << line << endl;
45         stringstream ss;
46         ss << line;
47         ss >> num;
48         cout << num << endl;
49     }
50 
51     // Close the file
52     rfile.close();
53 
54     return 0;
55 }
View Code

相关文章:

  • 2021-09-27
  • 2021-10-25
  • 2021-11-09
  • 2021-08-23
  • 2021-10-07
  • 2021-10-23
  • 2022-01-22
猜你喜欢
  • 2021-08-09
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-15
  • 2022-12-23
相关资源
相似解决方案