3、泛型编程风格-C++

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

答案代码:

#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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值