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,"