C++ Primer学习笔记之第12章-泛型-踩在巨人的脚背上-prog12.cpp程序

类别:编程语言 点击:0 评论:0 推荐:
    学好泛型,受用无穷!
  

STL的容器都是定义在std namespace;所以光是包含相应的头文件是不可取的,至少加上:

       using namespace std; 或者是:using std:: ×××(你用的容器);

在预处理器的后面。

 

其实对于gnu c++来说,.c后缀和.cpp后缀没有什么分别,但对于MS VS来说就是C程序和C++程序的区别了;

/*************************************************************************

其实lippman先生写的下面的这个程序的执行并非像是书上的那么理想。在处理大写字母和符号上有些问题(他老人家很可能是故意的)。此程序的主要功能是:从两个text files中读取string,每一个text files 都被放入string vector中, 而这两个string vector又被放入一个string vector中,这样泛型算法处理的对象就有了,然后执行各种泛型操作。这个程序皆是由泛型算法+函数对象进行串处理。有些事情说来真是悲哀:越是看到最后越觉是理所当然。of course

是我们该出手的时候了,我们要修改这个程序,使这个玩具完善起来。我们模仿第六章的做法对string vector先进行大小写字母的转换,然后,擦除句中的标点,最后再进行一系列的操作。

*************************************************************************/

#include <vector>

#include <string>

#include <algorithm>

#include <iterator>

//#include <iostream.h>

#include <iostream>

 

using namespace std;

 

class GreaterThan {

public:

       GreaterThan( int size = 6 ) : _size( size ){}

       int size() { return _size; }

 

       bool operator()(const string & s1) {

              return s1.size() > 6;

        }

 

private:

       int _size;

};

 

template <class Type>

class PrintElem {

public:

       void operator()( const Type &elem )

       {

              ++_cnt;

              if ( _cnt % 8 == 0 ) { cout << endl; }

              cout << elem << " ";

       }

      

private:

       static int _cnt;

};

 

template < class Type >

          int PrintElem<Type>::_cnt = 0;

 

class LessThan {

public:

       bool operator()(const string & s1, const string & s2 ) {

            return s1.size() < s2.size();

           }

};

 

typedef vector<string> textwords;

 

void process_vocab( vector<textwords> *pvec )

{

       if ( ! pvec )

            // issue warning message

            return;

 

       vector< string > texts;

 

       vector<textwords>::iterator iter = pvec->begin();

       for ( ; iter != pvec->end(); ++iter )

                 copy( (*iter).begin(), (*iter).end(), back_inserter( texts ));

 

       // sort the elements of texts

       sort( texts.begin(), texts.end() );

       for_each( texts.begin(), texts.end(), PrintElem<string>() );

 

       cout << endl << endl;

 

       // delete all duplicate elements

       vector<string>::iterator it;

       it = unique( texts.begin(), texts.end() );

       texts.erase( it, texts.end() );

       for_each( texts.begin(), texts.end(), PrintElem<string>() );

 

       cout << endl << endl;

 

       stable_sort( texts.begin(), texts.end(), LessThan() );

       for_each( texts.begin(), texts.end(), PrintElem<string>() );

 

       cout << endl << endl;

 

       // count number of strings greater than length 6

       int cnt = 0;

 

       // obsolete form of count -- standard changes this

       cnt = count_if( texts.begin(), texts.end(), GreaterThan());

 

       cout << "Number of words greater than length six are "

                 << cnt << endl;

 

       // ...

 

       static string rw[] = { "and", "if", "or", "but", "the" };

       vector<string> remove_words( rw, rw+5 );

 

       vector<string>::iterator it2 = remove_words.begin();

       for ( ; it2 != remove_words.end(); ++it2 ) {

              int cnt = 0;

              // obsolete form of count -- standard changes this

       cnt = count( texts.begin(), texts.end(), *it2);

      

              cout << cnt << " instances removed:  "

                   << (*it2) << endl;

      

                  texts.erase(

                     remove(texts.begin(),texts.end(),*it2),

                     texts.end()

            );

     }

 

       cout << endl << endl;

       for_each( texts.begin(), texts.end(), PrintElem<string>() );

}

 

typedef vector<string>::difference_type diff_type;

#include <fstream>

 

main()

{

     vector<textwords> sample;

     vector<string>          t1, t2;

     string                        t1fn, t2fn;

 

     cout << "text file #1: "; cin >> t1fn;

     cout << "text file #2: "; cin >> t2fn;

 

     ifstream infile1( t1fn.c_str());

     ifstream infile2( t2fn.c_str());

 

     istream_iterator< string > input_set1( infile1 ), eos;

     istream_iterator< string > input_set2( infile2 );

 

     copy( input_set1, eos, back_inserter( t1 ));

     copy( input_set2, eos, back_inserter( t2 ));

 

     sample.push_back( t1 ); sample.push_back( t2 );

     process_vocab( &sample );

}

首先我们增加过滤标点符号的函数:

void filter_text(vector<string>&text)

{

    const string filt_elems( "\",.;:!?)(\\/" );

    if( filt_elems.empty() ) return;

    vector<string>::iterator iter = text.begin();

    vector<string>::iterator iter_end = text.end();

    while( iter != iter_end ){

           string::size_type pos = 0;

           while((pos = (*iter).find_first_of(filt_elems,pos))

                                                            != string::npos )

                                                            (*iter).erase(pos,1);

                                                            ++iter;

    }

}

其次增加转换大写为小写的函数:

void strip_caps(vector<string>&text)

{

          

    const string caps( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" );

    vector<string>::iterator iter = text.begin();

    vector<string>::iterator iter_end = text.end();

    while( iter != iter_end ){

           string::size_type pos = 0;

           while((pos = (*iter).find_first_of(caps,pos))

                                                            != string::npos )

                                                            (*iter)[pos] = tolower( (*iter)[pos] );

                                                            ++iter;

    }

}

OK,在适当的位置插入这两个函数。

最终的程序如下所示:

 

#include <vector>

#include <string>

#include <algorithm>

#include <iterator>

#include <iomanip>

#include <iostream>

 

using namespace std;

 

#include <ctype.h>

 

 

//prestandard syntax for <iostream>

//#include <iostream>


    //过滤标点符号的函数 

void filter_text(vector<string>&text)

{

    const string filt_elems( "\",.;:!?)(\\/" );

    if( filt_elems.empty() ) return;

    vector<string>::iterator iter = text.begin();

    vector<string>::iterator iter_end = text.end();

    while( iter != iter_end ){

           string::size_type pos = 0;

           while((pos = (*iter).find_first_of(filt_elems,pos))

                                                            != string::npos )

                                                            (*iter).erase(pos,1);

                                                            ++iter;

    }

}

 //大小写字母转换函数

void strip_caps(vector<string>&text)

{

          

    const string caps( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" );

    vector<string>::iterator iter = text.begin();

    vector<string>::iterator iter_end = text.end();

    while( iter != iter_end ){

           string::size_type pos = 0;

           while((pos = (*iter).find_first_of(caps,pos))

                                                            != string::npos )

                                                            (*iter)[pos] = tolower( (*iter)[pos] );

                                                            ++iter;

    }

}

 

 //所谓的函数对象,是为了函数所以对象

class GreaterThan {

public:

    GreaterThan( int sz = 6 ) : _size( sz ) { }

    int size() { return _size; }

 

    bool operator()( const string & s1 )

    { return s1.size() > _size; }

 

private:

    int _size;

};

 

class PrintElem {

public:

    PrintElem( int lineLen = 8 )

        : _line_length( lineLen ), _cnt( 0 )

    { }

 

    void operator()( const string &elem ) {

        ++_cnt;

        if ( _cnt % _line_length == 0 ) {

            cout << '\n';

        }

        cout << elem << " ";

    }

 

private:

    int _line_length;

    int _cnt;

};

 

// a function object -- the operation is

// implemented as an instance of operator()

class LessThan {

public:

    bool operator()( const string & s1,

                     const string & s2 )

    {

        return s1.size() < s2.size();

    }

};

 

// The following code has been commented because 'allocator'

// being a template class, should be given template arguments.

// typedef vector<string, allocator> textwords;

typedef vector<string> textwords;

 

// The following code has been commented because 'allocator'

// being a template class, should be given template arguments.

// void process_vocab( vector<textwords, allocator> *pvec )

void process_vocab( vector<textwords> *pvec )

{

    if ( !pvec ) {

                  //test pointer to vector<textwords>

        // issue warning message

        cout << "Invalid argument.....\n";

        return;

    }

 

    // The following code has been commented because 'allocator'

    // being a template class, should be given template arguments.

    // vector<string, allocator> texts;

    vector<string> texts;

 

    // The following code has been commented because 'allocator'

    // being a template class, should be given template arguments.

    // vector<textwords, allocator>::iterator iter;

    vector<textwords>::iterator iter;

    for ( iter = pvec->begin(); iter != pvec->end(); ++iter )

        copy( ( *iter ).begin(), ( *iter ).end(),

              back_inserter( texts ) );

   

    //before operate

    cout << "\nBefor operating 'texts' contains:\n";

    for_each( texts.begin(), texts.end(), PrintElem() );

    cout << "\n\n";

   

 

    filter_text(texts);

    strip_caps(texts);

      

    // sort the elements of texts

    sort( texts.begin(), texts.end() );

 

    // ok, let's see what we have

    cout << "\nAfter applying 'sort()' the vector 'texts' contains: \n";

    for_each( texts.begin(), texts.end(), PrintElem() );

    cout << "\n\n";    // just to separate display output

 

    // delete all duplicate elements

    // vector<string, allocator>::iterator it;

    vector<string>::iterator it;

    it = unique( texts.begin(), texts.end() );

    //ok, let's see what we have now

     cout << "\nAfter applying 'unique()' the vector 'texts'"

                        <<" contains: \n";

     for_each( texts.begin(), texts.end(), PrintElem() );

     cout << "\n\n";

   

    texts.erase( it, texts.end() );

    // ok, let's see what we have now

    cout << "\nAfter applying 'erase()' the vector 'texts'"

         << " contains: \n";

    for_each( texts.begin(), texts.end(), PrintElem() );

    cout << "\n\n";

 

    // sort the elements based on default length of 6

    // stable_sort() preserves ordering of equal elements ...

    stable_sort( texts.begin(), texts.end(), LessThan() );

    cout << "\nAfter applying 'stable_sort()' the vector 'texts' contains: \n";

    for_each( texts.begin(), texts.end(), PrintElem() );

 

    cout << "\n\n";

 

    // count number of strings greater than length 6

    int cnt = 0;

 

    // obsolete form of count -- standard changes this

    cnt = count_if ( texts.begin(), texts.end(), GreaterThan() );

 

    cout << "Number of words greater than length six are "

         << cnt << endl;

 

    static string rw[] = { "and", "if", "or", "but", "the" };

 

    // vector<string, allocator> remove_words( rw, rw + 5 );

    vector<string> remove_words( rw, rw + 5 );

 

    // vector<string, allocator>::iterator it2 =

    vector<string>::iterator it2 =

        remove_words.begin();

 

    for ( ; it2 != remove_words.end(); ++it2 )

    {

        int cnt = 0;

 

        // unobsolete form of count -- standard changes this

        cnt = count( texts.begin(), texts.end(), *it2);

 

        cout << cnt << " instances removed:  "

             << ( *it2 ) << endl;

 

        texts.erase(

            remove( texts.begin(), texts.end(), *it2 ),

            texts.end()

        );

    }

    cout << "\n\n";

    cout << "\nAfter applying 'erase()' the vector 'texts' contains: \n";

    for_each( texts.begin(), texts.end(), PrintElem() );

}

 

// difference type is the type capable of holding the result

// of subtracting two iterators of a container

// -- in this case, of a string vector ...

// ordinarily, this is handled by default ...

 

// The following code has been commented because 'allocator' being a

// template class, should be given template arguments.

// typedef vector<string>::difference_type diff_type;

typedef vector<string>::difference_type diff_type;

 

// prestandard header syntax for <fstream>

#include <fstream>

 

int main()

{

    vector<textwords> sample;

    // The following code has been commented because 'allocator' being a

    // template class, should be given template arguments.

    // vector<string, allocator> t1, t2;

    vector<string> t1, t2;

    string t1fn, t2fn;

 

    // request input files from user ...

    // should do some error checking in real-world program

    cout << "text file #1(inFile.txt): ";

    cin >> t1fn;

    cout << "text file #2(inFile1.txt): ";

    cin >> t2fn;

 

    // open the files

    ifstream infile1( t1fn.c_str() );

    ifstream infile2( t2fn.c_str() );

 

    // special form of iterator

    // ordinarily, diff_type is provided by default ...

    istream_iterator<string> input_set1( infile1 ),

                                        eos;

    istream_iterator<string> input_set2( infile2 );

 

    // special form of iterator

    copy( input_set1, eos, back_inserter( t1 ) );

    copy( input_set2, eos, back_inserter( t2 ) );

 

    sample.push_back( t1 ); sample.push_back( t2 );

    process_vocab( &sample );

    return 0;

}


    执行的结果如下:
      text file #1(inFile.txt): infile.txt

text file #2(inFile1.txt):infile1.txt

Befor operating 'texts' contains:

Alice Emma has long flowing red hair.

Her Daddy says when the wind blows through

her hair, it looks almost alive, like a

fiery bird in flight. "A beautiful fiery bird",

he tells her, "magical but untamed." "Daddy, shush,

there is no such thing," she tells him,

at the same time wanting him to tell

her more. Shyly, she asks, "I mean, Daddy,

is there?" magical but untamed. "Daddy, shush, there

is no such thing,"

 

 

After applying 'sort()' the vector 'texts' contains:

a a alice alive almost asks at

beautiful bird bird blows but but daddy daddy

daddy daddy emma fiery fiery flight flowing hair

hair has he her her her her him

him i in is is is it like

long looks magical magical mean more no no

red same says she she shush shush shyly

such such tell tells tells the the there

there there thing thing through time to untamed

untamed wanting when wind

 

 

After applying 'unique()' the vector 'texts' contains:

a alice alive almost asks at beautiful

bird blows but daddy emma fiery flight flowing

hair has he her him i in is

it like long looks magical mean more no

red same says she shush shyly such tell

tells the there thing through time to untamed

wanting when wind she she shush shush shyly

such such tell tells tells the the there

there there thing thing through time to untamed

untamed wanting when wind

 

 

After applying 'erase()' the vector 'texts' contains:

a alice alive almost asks at beautiful

bird blows but daddy emma fiery flight flowing

hair has he her him i in is

it like long looks magical mean more no

red same says she shush shyly such tell

tells the there thing through time to untamed

wanting when wind

 

 

After applying 'stable_sort()' the vector 'texts' contains:

a i at he in is it

no to but has her him red she

the asks bird emma hair like long mean

more same says such tell time when wind

alice alive blows daddy fiery looks shush shyly

tells there thing almost flight flowing magical through

untamed wanting beautiful

 

Number of words greater than length six are 6

0 instances removed:  and

0 instances removed:  if

0 instances removed:  or

1 instances removed:  but

1 instances removed:  the

 

 

 

After applying 'erase()' the vector 'texts' contains:

a i at he in is it

no to has her him red she asks

bird emma hair like long mean more same

says such tell time when wind alice alive

blows daddy fiery looks shush shyly tells there

thing almost flight flowing magical through untamed wanting

beautiful

 

infile文件如下:

Alice Emma has long flowing red hair. Her Daddy says when the

wind blows through her hair, it looks almost alive, like a fiery

bird in flight. "A beautiful fiery bird", he tells her, "magical but

untamed."

"Daddy, shush, there is no such thing," she tells him, at

the same time wanting him to tell her more. Shyly, she asks,

"I mean, Daddy, is there?"

infile1文件如下:

magical but untamed. "Daddy, shush, there is no such thing,"

本文地址:http://com.8s8s.com/it/it25172.htm