答案代码:
#include<map>
#include<set>
#include<string>
#include<fstream>
#include <vector>
#include <algorithm>
#include <iostream>
#include<iterator>
using namespace std;
typedef vector<string> vstring;
//map<string,vstring> families;
void initalize_exclusion_set(set<string>&);
void process_file(map<string,int>&,const set<string>&,ifstream&);
void user_query(const map<string,int>&);
void display_word_count(const map<string,int>&,ofstream&);
void initalize_exclusion_set(set<string> &exs){
static string _excluded_words[25]={
"the","and","but","that","then","are","been",
"can","a","could","did","for","of",
"had","have","him","his","her","its","is",
"were","which","when","with","would"
};
exs.insert(_excluded_words,_excluded_words+25);
}
void process_file(map<string,int>& word_count,
const set<string>& exclude_set,ifstream& ifile){
string word;
while (ifile>>word) {
if(exclude_set.count(word)){
continue;
}
word_count[word]++;
}
}
void user_query(const map<string,int>& word_map)
{
string search_word;
cout<<"Please enter a word to search :q to quit";
cin>>search_word;
while (search_word.size()&&search_word!="q") {
map<string,int>::const_iterator it;
if((it=word_map.find(search_word))!=word_map.end())
cout<<"found! "<<it->first
<<" occurs "<<it->second
<<" times.\n";
else {
cout<<search_word
<<" was not found in text.\n";
}
cout<<"\nAnother search ?(q to quit) ";
cin>>search_word;
}
}
void display_word_count(const map<string,int>& word_map,ofstream &os){
map<string,int>::const_iterator
iter=word_map.begin(),
end_it =word_map.end();
while (iter!=end_it) {
os<<iter->first<<"("
<<iter->second<<")"<<endl;
++iter;
}
os <<endl;
}
int test_1(){
ifstream ifile("G:\\QT_project"
"\\EssentialCPP\\build-chap03-Desktop_Qt_5_9_8_MSVC2015_64bit-Debug\\column.txt");
ofstream ofile("G:\\QT_project"
"\\EssentialCPP\\build-chap03-Desktop_Qt_5_9_8_MSVC2015_64bit-Debug\\column.map");
if(!ifile||!ofile){
cerr<<"unable to open file -- bailing out!\n";
return -1;
}
set<string> exclude_set;
initalize_exclusion_set(exclude_set);
map<string,int> word_count;
process_file(word_count,exclude_set,ifile);
user_query(word_count);
display_word_count(word_count,ofile);
}
class LessThan{
public:
bool operator()(const string &s1,const string &s2){
return s1.size()<s2.size();
}
};
template<typename elemType>
void display_vector(const vector<elemType>&vec,ostream &os=cout,int len=8){
//vector<elemType>::cons
std::vector<elemType>::const_iterator iter=vec.begin(),end_it=vec.end();
int elem_cnt=1;
while (iter!=end_it) {
os<<*iter++<<(!(elem_cnt++%len)?'\n':' ');
}
os<<endl;
}
int test_2(){
ifstream ifile("G:\\QT_project"
"\\EssentialCPP\\build-chap03-Desktop_Qt_5_9_8_MSVC2015_64bit-Debug\\column.txt");
ofstream ofile("G:\\QT_project"
"\\EssentialCPP\\build-chap03-Desktop_Qt_5_9_8_MSVC2015_64bit-Debug\\column.map");
if(!ifile||!ofile){
cerr<<"unable to open file -- bailing out!\n";
return -1;
}
vector<string > text;
string word;
while (ifile>>word) {
text.push_back(word);
}
sort(text.begin(),text.end(),LessThan());
display_vector(text,ofile);
}
//ifstream -- 从已有的文件读
//ofstream -- 向文件写内容
//fstream -- 打开文件供读写
//getline()是标准库函数,它从文件读取一行内容,其第三个参数用来指定行末字符。默认的行末字符为换行符,
void populate_map(ifstream &nameFile,map<string,vstring> &families)
{
string textline;
while (getline(nameFile,textline)) {
string fam_name;
vector<string> child;
string::size_type pos =0,prev_pos=0,text_size=textline.size();
//ok :找出以空格分隔开来的所有单字
while ((pos=textline.find_first_of(' ',pos))!=string::npos) {
//计算子字符串的终点
string::size_type end_pos=pos-prev_pos;
//倘若prev_pos并未设置(或说其值为0,),那么读到的单字就是家庭姓氏,否则我们就————读取孩子们的名字了
if(!prev_pos)
fam_name=textline.substr(prev_pos,end_pos);
else {
child.push_back(textline.substr(prev_pos,end_pos));
}
prev_pos=++pos;
}
//选择处理最后一个孩子的名字
if(prev_pos<text_size)
child.push_back(textline.substr(prev_pos,pos-prev_pos));
if(!families.count(fam_name))
families[fam_name]=child;
else {
cerr<<"Oops! We already have a"<<fam_name<<" family in our map!\n";
}
}
}
//下面函数读取家庭姓氏以及孩子们的名字。string的函数substr(),并传入两个字符位置,借此切分出一个新的string,其内容正是旧字符中的
//两个字符位置间的子字符串。最后如果读入的姓氏并不在map内,就将该姓氏放入。
void display_map(const map<string,vstring> &familes,ostream &os){
map<string,vstring>::const_iterator it=familes.begin(),end_it=familes.end();
while (it!=end_it) {
os<<" The "<<it->first<<" family ";
if(it->second.empty())
os<<" has no children\n";
else {
//打印出vector 内的小孩子名字
os<< " has "<<it->second.size()<<" children: ";
vector<string>::const_iterator
iter=it->second.begin(),
end_iter= it->second.end();
while (iter!=end_iter) {
os<<*iter<< " ";
++iter;
}
os<<endl;
}
++it;
}
}
//查询某个家庭是否位于数据文件中。
void query_map(const string &family,const map<string,vstring> &families){
map<string,vstring>::const_iterator
it=families.find(family);
if(it==families.end()){
cout<<"sorry .the "<<family
<<"is not currently entered.\n";
return;
}
cout<<" the "<<family;
if(!it->second.size())
cout<<" has no children\n";
else {//打印所有小孩子的名字
cout<<" has "<<it->second.size()<<" children: ";
vector<string>::const_iterator
iter=it->second.begin(),
end_iter=it->second.end();
while (iter!=end_iter) {
cout<<*iter<< " ";
++iter;
}
cout<<endl;
}
}
int test_3(){
map<string,vstring> families;
ifstream nameFile("G:\\QT_project"
"\\EssentialCPP\\build-chap03-Desktop_Qt_5_9_8_MSVC2015_64bit-Debug\\families.txt");
if(!nameFile){
cerr<<"unable to find families.txt file . bailing out !\n";
return -1;
}
populate_map(nameFile,families);
string family_name;
while (1) {//除非用户表示要离开,否则一直执行下去
cout<<"please enter a family name or q to quit";
cin>>family_name;
if(family_name=="q")
break;
query_map(family_name,families);
}
display_map(families,cout);
}
//class even_elem {
//public:
// bool operator()( int elem )
// { return elem%2 ? false : true; }
//};
class even_elem{
public:
bool operator()(int elem){
return elem%2 ? false:true;
}
};
void test_4()
{
vector<int > input;
istream_iterator<int> in(cin),eos;
//输出文件 偶数文件 奇数文件
ofstream even_file("G:\\QT_project\\EssentialCPP\\build-chap03-Desktop_Qt_5_9_8_MSVC2015_64bit-Debug\\debug\\even_file"),
odd_file("G:\\QT_project\\EssentialCPP\\build-chap03-Desktop_Qt_5_9_8_MSVC2015_64bit-Debug\\debug\\odd_file");
if(!even_file|!odd_file){
cerr << "arghh!! unable to open the output files. bailing out!";
return ;
}
copy(in,eos,back_inserter(input));
//泛型函数partition区分奇偶函数。当然同时配合 function object even_elem()的使用,后者在传入时为偶数是会返回true。
vector<int>::iterator division=partition(input.begin(),input.end(),even_elem());
//再将这两个ostream_iterator绑定至相应的ofstream对象上。第二个参数代表每个元素输出时的分隔符
ostream_iterator<int> even_iter(even_file,"\n"),
odd_iter(odd_file," ");
//最后 再以泛型函数copy(),将已经被分开的奇偶元素分别输出至不同的文件
copy(input.begin(),division,even_iter);//从input开始取 division的前部分为偶数
copy(division,input.end(),odd_iter);//division后半部分为奇数 直到input end
}
void ex3_4()
{
vector< int > input;
istream_iterator<int> in( cin ), eos;
ofstream even_file( "even_file" ),
odd_file( "odd_file" );
if ( ! even_file || ! odd_file ){
cerr << "arghh!! unable to open the output files. bailing out!";
return ;
}
copy( in, eos, back_inserter( input ));
vector<int>::iterator division =
partition( input.begin(), input.end(), even_elem() );
ostream_iterator<int> even_iter( even_file, "\n" ),
odd_iter( odd_file, " " );
copy( input.begin(), division, even_iter );
copy( division, input.end(), odd_iter );
}
int main()
{
//test_3();
//test_4();
ex3_4();
cout << "Hello World!" << endl;
return 0;
}