一个文本行排序程序(From 《泛型编程与STL》)

就像高中班主任对待班上两个极端的学生一样:一个极优秀、一个成绩极差。我承认vc6的IDE环境让我无法割舍,但是它对模板类型的嵌套,支持得实在不怎么样呢!对于STL,没什么好说的,一个轻松处理文本行排序的程序,就这么几下搞定;记得在C++prime中讲述的例子程序吗?感慨颇多吧!
  1. #include <utility>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <vector>
  5. using namespace std;
  6. struct strtab_print
  7. {
  8.     ostream& out;
  9.     strtab_print(ostream& os) : out(os){}
  10.     typedef vector<char>::iterator strtab_iterator;
  11.     void operator()(const pair<strtab_iterator,strtab_iterator>& s) const
  12.     {
  13.         copy(s.first,s.second,ostream_iterator<char>(out));
  14.     }
  15. };
  16. struct strtab_cmp
  17. {
  18.     typedef vector<char>::iterator strtab_iterator;
  19.     bool operator()(const pair<strtab_iterator,strtab_iterator>& x,const pair<strtab_iterator,strtab_iterator>& y) const
  20.     {
  21.         return lexicographical_compare(x.first,x.second,y.first,y.second);
  22.     }
  23. };
  24. void main()
  25. {
  26.     vector<char> strtab;
  27.     char c;
  28.     while (cin.get(c))
  29.     {
  30.         strtab.push_back(c);
  31.     }
  32.     typedef vector<char>::iterator strtab_iterator;
  33. //  vector<pair<strtab_iterator,strtab_iterator>> lines;    //这样就不行了
  34.     typedef pair<strtab_iterator,strtab_iterator> PAIR_STRTAB_ITERATOR;//增加一个typedef 定义,就可以了;
  35.     vector<PAIR_STRTAB_ITERATOR> lines;
  36.     strtab_iterator start = strtab.begin();
  37.     while (start != strtab.end())
  38.     {
  39.         strtab_iterator next = find(start, strtab.end(),'/n');
  40.         if (next!=strtab.end())
  41.             ++next;
  42.         lines.push_back(make_pair(start,next));
  43.         start = next;
  44.     }
  45.     sort(lines.begin(),lines.end(),strtab_cmp());
  46.     for_each(lines.begin(),lines.end(),strtab_print(cout));
  47. }

程序执行:

输入:

boluo is good!

and everyone is good,too!

here comes the bus!

ctrl+Z 回车

输出:

and everyone is good,too!

boluo is good!

here comes the bus!

排序成功:)

那么,如何想到设计这样的算法呢?

首先我要想的是:算法的根本目的是在于“高效地排序”,而不在于程序如何存储数据。如果从这个出发点考虑,采用指针,肯定比使用string和sort要快速多了——sort里面涉及到拷贝操作呢!如果sort直接对string进行拷贝的话,效率可想而知!

在借助指针的时候,如何表示一行文本呢?那么只能是pair类型了:一个指针保存文本行的首地址,一个指针保存文本行的尾地址。同时,我们需要使用lexicographical_compare函数帮助我们进行排序,而这个函数需要pair进行操作:显然,我们应该将每行文本存储在vector<char>里面,然后将vector每行的begin和end指针make_pair传递给lexicographical_compare函数。

很显然:功能决定了算法,算法又决定了我们的数据结构!

最好能够熟练地将这个程序自己编写一遍呢!

 

下面是程序的框架,对于框架完成后,细节想清楚了,慢慢补全就可以了:

  1. #include <vector>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <string>
  5. using namespace std;
  6. struct strtab_cmp
  7. {
  8.     operator()(const pair&,const pair& y)
  9.     {
  10.         return lexicographical_compare(x....y);
  11.     }
  12. };
  13. void main()
  14. {
  15.     vector<char> strtab;
  16.     //输入文件
  17.     //分行形成lines
  18.     while (/*所有文本没处理完*/)
  19.     {
  20.         vector<char>::iterator start,end,next;
  21.         //  start 为行起始、next为行末尾;通过循环进行处理
  22.         make_pair(start,next);
  23.         vector<pair</*start的类型*/,/*start的类型*/>> lines;
  24.     }
  25.     
  26.     //对lines进行排序
  27.     sort(lines.begin().lines.end(),strtab_cmp());//根据函数对象的结果进行sort交换
  28.     //输出
  29.     for_each();
  30. }

你可能感兴趣的:(一个文本行排序程序(From 《泛型编程与STL》))