zoukankan      html  css  js  c++  java
  • STL,Template,继承,多态的例子

      1 //使用map结构进行单词的转换,第一个参数为提供转换格式的文件,第二个参数为输入文件
      2 #include <iostream>
      3 #include <map>
      4 #include <fstream>
      5 #include <sstream>
      6 #include <string>
      7 using namespace std;
      8 
      9 int main( int argc, char **argv)
     10 {
     11     map<string,string> trans_map;
     12     string key, value;
     13     if( argc != 3)
     14         throw runtime_error("wrong number of arguments");
     15     ifstream map_file;
     16     map_file.open(argv[1]);
     17     if (!map_file)
     18         throw runtime_error("no transformation file");
     19     while ( map_file >> key >> value)
     20         trans_map.insert(make_pair(key, value));
     21 
     22     ifstream input;
     23     input.open(argv[2]);
     24     if( !input)
     25         throw runtime_error("no input file");
     26     string line;
     27     while( getline( input, line))
     28     {
     29         istringstream stream(line);
     30         string word;
     31         bool firstword  = true;
     32         while( stream >> word)
     33         {
     34             map<string, string>::const_iterator map_it = trans_map.find(word);
     35             if ( map_it != trans_map.end())
     36                 word  = map_it->second;
     37             if( firstword)
     38                 firstword = false;
     39             else
     40                 cout << " ";
     41             cout << word;
     42         }
     43         cout << endl;
     44     }
     45     return 0;
     46 }
     47 
     48 //容器的综合应用:文本查询程序
     49 #include <iostream>
     50 #include <string>
     51 #include <fstream>
     52 #include <sstream>
     53 #include <map>
     54 #include <set>
     55 #include <vector>
     56 #include <algorithm>
     57 #include <iterator>
     58 using namespace std;
     59 
     60 class TextQuery
     61 {
     62 public:
     63     typedef vector<string>::size_type  line_no;
     64     void read_file( ifstream &is)
     65     {
     66         store_file(is);
     67         build_map();
     68     }
     69     set<line_no> run_query(const string&) const;
     70     string text_line(line_no) const;
     71     line_no size() const
     72     {
     73         return (line_no)lines_of_text.size();
     74     }
     75 private:
     76     void store_file( ifstream &);
     77     void build_map();
     78     vector<string> lines_of_text;                       //文件中的每一行是该vector对象的一个元素
     79     map <string, set<line_no> >word_map;      //将单词的行号存入set对象中。使用set可以保证每行只有一个条目,而且自动按升序排列
     80                                                                       //使用一个map容器将每个单词与一个set容器关联起来,该set对象记录此单词所在行号
     81 };
     82 //存储输入文件
     83 void TextQuery::store_file(ifstream &is)
     84 {
     85     string textline;
     86     while( getline(is,textline) )
     87         lines_of_text.push_back(textline);
     88 }
     89 //建立单词map容器
     90 void TextQuery::build_map()
     91 {
     92     for (line_no line_num=0; line_num != lines_of_text.size(); ++line_num)
     93     {
     94            istringstream line(lines_of_text[line_num]);
     95         string word;
     96         while ( line >> word)
     97             word_map[word].insert(line_num);
     98     }
     99 }
    100 //支持查询
    101 set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const
    102 {
    103     map<string, set<line_no> >::const_iterator loc = word_map.find(query_word);
    104     if ( loc == word_map.end())
    105         return set<line_no>();
    106     else
    107         return loc->second;
    108 }
    109 
    110 //run_query 返回值的使用
    111 string TextQuery::text_line(line_no line) const
    112 {
    113     if( line < lines_of_text.size())
    114         return lines_of_text[line];
    115     throw out_of_range("line number out of range");
    116 }
    117 
    118 //输出结果
    119 void print_results(const set<TextQuery::line_no> & locs,const string& sought, const TextQuery &file)
    120 {
    121     typedef set<TextQuery::line_no> line_nums;
    122     line_nums::size_type size = locs.size();
    123     cout << "\n" <<sought << " occurs" << size <<" " <<endl;
    124     line_nums::const_iterator it = locs.begin();
    125     for ( ; it != locs.end(); ++it)
    126     {
    127         cout <<"\t(line"<< (*it)+1<<") " 
    128             << file.text_line(*it) <<endl;
    129     }
    130 }
    131 
    132 int main( int argc, char **argv)
    133 {
    134     ifstream infile;
    135     infile.open(argv[1]);
    136     if( !infile)
    137         throw runtime_error("no input file");
    138     TextQuery tq;
    139     tq.read_file(infile);
    140     while(true)
    141     {
    142         cout <<"enter word to look for, or q to quit; ";
    143         string s;
    144         cin >> s;
    145         if ( !cin || s == "q") 
    146             break;
    147         set<TextQuery::line_no> locs = tq.run_query(s);
    148         print_results(locs,s,tq);
    149     }
    150     return 0;
    151 }
    152 
    153 //文本查询面向对象的实现,可支持与,或,非查询,使用的是继承和动态绑定
    154 //查询类的抽象基类
    155 class Query_base
    156 {
    157     friend class Query;                                                            // 友元类,可以访问Query_base成员函数和变量
    158 protected:
    159     typedef TextQuery::line_no line_no;
    160     virtual ~Query_base() { }                                                      //虚析构函数
    161 private:
    162     virtual set<line_no> eval(const TextQuery&) const =0;        //纯虚函数,每个派生类都有自己的实现
    163     virtual ostream& display( ostream & = cout) const =0;
    164 };
    165 
    166 //用户计数的句柄类,它指向Query_base派生类的对象
    167 class Query{
    168     friend Query operator ~(const Query &);                                //友元函数重载运算符
    169     friend Query operator | (const Query &, const Query &);
    170     friend Query operator & (const Query &, const Query &);
    171     friend ostream & operator <<(ostream &os,const Query &q)
    172     {
    173         return q.display(os);
    174     }
    175 public:
    176     Query( const string&);
    177     Query(const Query &c): q(c.q), use(c.use)
    178     { ++*use;}
    179     ~Query() { decr_use(); }
    180     Query & operator =(const Query &);
    181     set<TextQuery::line_no> eval(const TextQuery &t) const 
    182     {
    183         return q->eval(t);
    184     }
    185     ostream &display( ostream &os) const
    186     {
    187         return q->display(os);
    188     }
    189 private:
    190     Query(Query_base * query): q(query), use(new size_t(1))
    191     { }
    192     Query_base *q;                                                                            //基类指针,可以指向派生类对象,从而实现多态
    193     size_t *use;
    194     void decr_use()
    195     {
    196         if( --*use == 0) 
    197         { 
    198             delete q; 
    199             delete use;
    200         }
    201     }
    202 };
    203 
    204 inline Query operator & (const Query &lhs, const Query &rhs)
    205 {
    206     return new AndQuery(lhs, rhs);
    207 }
    208 inline Query operator | (const Query &lhs, const Query &rhs)
    209 {
    210     return new OrQuery(lhs,rhs);
    211 }
    212 inline Query operator ~(const Query &oper)
    213 {
    214     return new NotQuery(oper);
    215 }
    216 
    217 
    218 class WordQuery: public Query_base
    219 {
    220     friend class Query;
    221     WordQuery(const string &s):query_word(s){ }
    222     set<line_no> eval(const TextQuery &t ) const 
    223     {
    224         return t.run_query(query_word);
    225     }
    226     ostream& display( ostream &os ) const 
    227     {
    228         return os << query_word;
    229     }
    230     string query_word;
    231 };
    232 
    233 
    234 class NotQuery: public Query_base
    235 {
    236     friend Query operator ~ (const Query &);
    237     NotQuery(Query q): query(q) { }
    238     set<line_no> eval( const TextQuery &) const;
    239     ostream & display(ostream &os) const
    240     {
    241         return os << "~(" <<  query << ")";
    242     }
    243     const Query query;
    244 };
    245 
    246 set<TextQuery::line_no> NotQuery::eval(const TextQuery & file) const
    247 {
    248     set<line_no> has_val = query.eval(file);
    249     set<line_no> ret_lines;
    250     for ( line_no n=0; n != file.size();  ++n)
    251         if( has_val.find(n) == has_val.end() )
    252             ret_lines.insert(n);
    253     return ret_lines;
    254 }
    255 
    256 class BinaryQuery: public Query_base
    257 {
    258 protected:
    259     BinaryQuery(Query left, Query right, string op) : lhs(left), rhs(right), oper(op)
    260     { }
    261     ostream& display( ostream &os) const
    262     {
    263         return os << "(" << lhs << " " << oper << " "
    264             <<rhs << ")";
    265     }
    266     const Query lhs, rhs;
    267     const string oper;
    268 };
    269 
    270 class AndQuery: public BinaryQuery
    271 {
    272     friend Query operator& (const Query&,const Query&);
    273     AndQuery(Query left, Query right) : BinaryQuery(left,right,"&") { }
    274     set<line_no> eval(const TextQuery &) const;
    275 };
    276 
    277 set<TextQuery::line_no> AndQuery::eval(const TextQuery & file) const
    278 {
    279     set<line_no> left = lhs.eval(file), right = rhs.eval(file);
    280     set<line_no> ret_lines;
    281     set_intersection(left.begin(), left.end(),
    282                             right.begin(), right.end(), 
    283                             inserter(ret_lines, ret_lines.begin() ));
    284     return ret_lines;
    285 }
    286 
    287 class OrQuery : public BinaryQuery
    288 {
    289     friend Query operator|(const Query&, const Query&);
    290     OrQuery(Query left,Query right) : BinaryQuery(left,right,"|") { }
    291     set<line_no> eval(const TextQuery &) const;
    292 };
    293 
    294 set<TextQuery::line_no> OrQuery::eval( const TextQuery &file) const
    295 {
    296     set<line_no> right = rhs.eval(file),
    297         ret_lines = lhs.eval(file);
    298     ret_lines.insert(right.begin(), right.end() );
    299     return ret_lines;
    300 }
    301 
    302 
    303 //完整的模版Queue类
    304 template< class Type> class Queue;
    305 template <class T> ostream& operator << ( ostream &, const Queue<T>&);
    306 template <class Type>
    307 //队列中元素
    308 class QueueItem{
    309 public:
    310     friend class Queue<Type>;                                                        //声明为友元类
    311     friend ostream & operator << <Type> ( ostream&, const Queue<Type>&);
    312     QueueITem(const Type &t) : item(t), next(0) { }
    313     Type item;
    314     QueueItem *next;
    315 };
    316 
    317 //支持具体操作的队列类
    318 template<class Type> 
    319 class Queue
    320 {
    321     friend ostream & operator << <Type> (ostream &, const Queue<Type> &);
    322 public:
    323     Queue( ): head(0),tail(0) { }
    324     template<class It>
    325     Queue(It beg, It end): head(0), tail(0) { copy_elems(beg,end); }
    326     Queue(const Queue &Q) : head(0), tail(0) { copy_elems(Q); }
    327     Queue& operator = (const Queue&);
    328     ~Queue( ) { destroy( ); }
    329     template<class Iter> void assign(Iter, Iter);
    330     Type & front( ) { return head->item; }
    331     const Type &front() const { return head->item; }
    332     void push(const Type &);
    333     void pop( );
    334     bool empty( ) const {
    335         return head == 0;
    336     }
    337 private:
    338     QueueItem<Type> *head;
    339     QueueItem<Type> *tail;
    340     void destroy();
    341     void copy_elems(const Queue&);
    342     template <class Iter> void copy_elems(Iter, Iter);
    343 };
    344 
    345 template <class Type> 
    346 void Queue<Type>::destroy()
    347 {
    348     while ( !empty() )
    349         pop();
    350 }
    351 
    352 template<class Type>
    353 void Queue<Type>::pop()
    354 {
    355     QueueItem<Type> *p = head;
    356     head = head->next;
    357     delete p;
    358 }
    359 
    360 template<class Type>
    361 void Queue<Type>::push( const Type &val)
    362 {
    363     QueueItem<Type> *pt = new QueueItem<Type>(val);
    364     if(empty())
    365         head = tail = pt;
    366     else
    367     {
    368         tail ->next = pt;
    369         tail = pt;
    370     }
    371 }
    372 
    373 template<class Type>
    374 void Queue<Type>::copy_elems( const Queue &orig)
    375 {
    376     for ( QueueItem<Type> *pt = orig.head; pt; pt = pt->next)
    377         push( pt->item);
    378 }
    379 
    380 
    381 
    382 //定义泛型句柄类
    383 template <class T> 
    384 class Handle
    385 {
    386 public:
    387     Handle(T *p=0) : ptr(p), use(new size_t(1) ) { }                //构造函数
    388     T & operator *();                                                            //重载运算符
    389     T * operator ->();
    390     const T& operator *() const;
    391     Handle( const Handle & h) : ptr(h.ptr), use(h.use)            //复制构造函数
    392     { ++*use;}
    393     Handle & operator = (const Handle&);                            //赋值函数
    394     ~Handle() { rem_ref(); }
    395 private:
    396     T* ptr;                                                                            //原始指针
    397     size_t *use;                                                                    //使用次数
    398     void rem_ref()                                                                //删除操作
    399     {
    400         if( --*use ==0)
    401         {
    402             delete ptr; 
    403             delete use;
    404         }
    405     }
    406 };
    407 
    408 template <class T>
    409 inline Handle<T> & Handle<T>::operator=( const Handle &rhs)
    410 {
    411     ++*rhs.use;
    412     rem_ref();
    413     ptr = rhs.ptr;
    414     use = rhs.use;
    415     return *this;
    416 }
    417 
    418 template<class T>
    419 inline T& Handle<T>::operator*()
    420 {
    421     if ( ptr) return *ptr;
    422     throw runtime_error("dereference of unbound Handle");
    423 }
    424 
    425 template<class T>
    426 inline T* Handle<T>::operator->()
    427 {
    428     if( ptr ) return ptr;
    429     throw runtime_error("access through unbound handle");
    430 }
  • 相关阅读:
    java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä'...解决
    Dos命令查看端口占用及关闭教程
    IDEA中Tomcat启动出现乱码
    ORA-12514:TNS:监听程序当前无法识别连接描述符中请求的服务
    MySQL 面试问题分析总结
    深入Cpython (编写一个Cpython 模块)
    使用docker构建简约高效的镜像
    深入理解C
    ELK 起航
    jquery
  • 原文地址:https://www.cnblogs.com/hzhida/p/2750302.html
Copyright © 2011-2022 走看看