标签:
在《编程珠玑》(第2版)的第1章(P4),作者对一个问题描述如下:
输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7。如果在输入文件中有任何整数重复出现就是致命错误。没有其他数据与该整数相关联。
输出:按升序排列的输入整数的列表。
约束:最多有(大约)1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10秒就不需要进一步优化了。
1MB大约有800万个位,如果需要排序的数据量小于或刚好等于1MB(单个数据的最大值不能超过1MB,而且任意两个数据不相等),那我们是否可以直接用这1MB个位来表示这个需要排序的数呢?问题当然是可以的。具体做法跟上一篇博文判断质数的几种方法的法五埃拉托斯特尼筛选法是一样的。这样做的结果,虽然占用空间大,但非常有时间优势。
作者在书中提出的做法是若给定文件中整数集合的位图数据结构,则可以分三阶段来编写程序:
1)将所有的位都置为0,从而将集合初始化为空;
2)通过读入文件中的每个整数来建立集合,将每个对应的位都置为1;
3)检验每一位,如果该位为1,就输出对应的整数,由此产生有序的输出文件。
本人实现的C++代码如下(如果已经知道输入的上限,就没有必要判断输入向量的最大值了,见下代码):
1 vector<int> SortNumbers::sort(vector<int> nums) 2 { 3 int sz = nums.size(); 4 int max = 0; 5 for (int i = 0; i < sz; i++) 6 { 7 if (nums[i] > max) 8 max = nums[i]; 9 } 10 11 vector<bool> isexist; 12 for (int i = 0; i < max + 1; i++) 13 isexist.push_back(false); 14 15 for (int i = 0; i < sz; i++) 16 isexist[nums[i]] = true; 17 18 vector<int> sorted; 19 for (int i = 0; i < max + 1; i++) 20 { 21 if (isexist[i]) 22 sorted.push_back(i); 23 } 24 25 return sorted; 26 }
完整的代码及单元测试代码如下:
源代码:
1 #ifndef SORTNUMBERS_H 2 #define SORTNUMBERS_H 3 4 #include <iostream> 5 #include <vector> 6 using namespace std; 7 8 class SortNumbers 9 { 10 public: 11 SortNumbers(); 12 virtual ~SortNumbers(); 13 vector<int> sort(vector<int> nums); 14 15 }; 16 17 SortNumbers::SortNumbers() 18 { 19 20 } 21 22 SortNumbers::~SortNumbers() 23 { 24 25 } 26 27 vector<int> SortNumbers::sort(vector<int> nums) 28 { 29 int sz = nums.size(); 30 int max = 0; 31 for (int i = 0; i < sz; i++) 32 { 33 if (nums[i] > max) 34 max = nums[i]; 35 } 36 37 vector<bool> isexist; 38 for (int i = 0; i < max + 1; i++) 39 isexist.push_back(false); 40 41 for (int i = 0; i < sz; i++) 42 isexist[nums[i]] = true; 43 44 vector<int> sorted; 45 for (int i = 0; i < max + 1; i++) 46 { 47 if (isexist[i]) 48 sorted.push_back(i); 49 } 50 51 return sorted; 52 } 53 54 55 #endif
Boost单元测试代码(只证明其正确性):
1 #define BOOST_TEST_MODULE SortNumbers_Test_Module 2 3 #include "stdafx.h" 4 #include "../SortNumbers/SortNumbers.hpp" 5 6 struct SortNumbers_Fixture 7 { 8 SortNumbers_Fixture() 9 { 10 test = new SortNumbers; 11 } 12 ~SortNumbers_Fixture() 13 { 14 delete test; 15 } 16 17 SortNumbers * test; 18 }; 19 20 BOOST_FIXTURE_TEST_SUITE(SortNumbers_Test_Suite, SortNumbers_Fixture) 21 22 BOOST_AUTO_TEST_CASE( Sort ) 23 { 24 int in_array[15] = { 22, 11, 17, 4, 5, 33, 13, 1, 20, 2, 30, 300, 222, 55, 43 }; 25 int out_array[15] = { 1, 2, 3, 4, 5, 11, 13, 17, 20, 22, 30, 43, 55, 222, 300 }; 26 vector<int> in, out; 27 for (int i = 0; i < 15; i++) 28 in.push_back(in_array[i]); 29 30 out = test->sort(in); 31 for (int i = 0; i < 15; i++) 32 BOOST_REQUIRE(out[i] = out_array[i]); 33 34 } 35 36 37 BOOST_AUTO_TEST_SUITE_END()
标签:
原文地址:http://www.cnblogs.com/xiehongfeng100/p/4341943.html