C++ Primer(第5版) 练习 12.30

练习 12.30 定义你自己版本的TextQuery和QueryResult类,并执行12.3.1节(第431页)中的runQueries函数。

环境:Linux Ubuntu(云服务器)
工具:vim

 

代码块
/*************************************************************************
	> File Name: ex12.30.cpp
	> Author: 
	> Mail: 
	> Created Time: Mon 22 Apr 2024 08:21:38 AM CST
 ************************************************************************/

#include<iostream>
#include<fstream>
#include<sstream>
#include<vector>
#include<map>
#include<set>
#include<memory>
using namespace std;

string make_plural(size_t ctr, string &word, const string &ending = "s"){
    int size = word.size();
    if(ctr <= 1){
        return word;
    }
    else{
        if(word[size-1] == 's' || word[size-1] == 'x' || (word[size-1] == 'h' && word[size-2] == 's') || (word[size-1] == 'h' && word[size-2] == 'c')){
            return word + "e" + ending;
        }
        else if(word[size-1] == 'y' && (word[size-2] != 'a' && word[size-2] != 'e' && word[size-2] != 'i' && word[size-2] != 'o' && word[size-2] != 'u')){
            word[size-1] = 'i';
            return word + "e" + ending;
        }
        else if((word[size-3] != 'a' && word[size-3] != 'e' && word[size-3] != 'i' && word[size-3] != 'o' && word[size-3] != 'u') && (word[size-2] != 'a' && word[size-2] != 'e' && word[size-2] != 'i' && word[size-2] != 'o' && word[size-2] != 'u')){
            if(word[size-1] == 'f'){
                word[size-1] = 'v';
                return word + ending;
            }
            else if(word[size-2] == 'f' && word[size-1] == 'e'){
                word[size-2] = 'v';
                return word + "e" + ending;
            }
        }
        else{
            return word + ending;
        }
    }
    return word;
}

class QueryResult;

class TextQuery{
    public:
    using line_no = vector<string>::size_type;
    TextQuery(ifstream &is);
    QueryResult query(const string &s) const;

    private:
    shared_ptr<vector<string>> file;
    map<string, shared_ptr<set<line_no>>> wm;
};

TextQuery::TextQuery(ifstream &is): file(new vector<string>){
    string text;
    while(getline(is, text)){
        file->push_back(text);
        int n = file->size() - 1;
        istringstream line(text);
        string word;
        while(line>>word){
            auto &lines = wm[word];
            if(!lines){
                lines.reset(new set<line_no>);
                lines->insert(n);
            }
        }
    }
}

class QueryResult{
    friend ostream &print(ostream &, const QueryResult &);
    public:
    QueryResult(string s, shared_ptr<set<TextQuery::line_no>> p, shared_ptr<vector<string>> f): sought(s), lines(p), file(f) {}

    private:
    string sought;
    shared_ptr<set<TextQuery::line_no>> lines;
    shared_ptr<vector<string>> file;
};

QueryResult TextQuery::query(const string &sought) const{
    static shared_ptr<set<line_no>> nodata(new set<line_no>);
    auto loc = wm.find(sought);
    if(loc == wm.end()){
        return QueryResult(sought, nodata, file);
    }
    else{
        return QueryResult(sought, loc->second, file);
    }
}

ostream &print(ostream &os, const QueryResult &qr){
    string na = "time";
    os<<qr.sought<<" occurs "<<qr.lines->size()<<" "<<make_plural(qr.lines->size(), na)<<endl;
    for(auto num : *qr.lines){
        os<<"\t(line "<<num + 1<<") "<<*(qr.file->begin() + num)<<endl;
    }
    return os;
}

void runQueries(ifstream &infile){
    TextQuery tq(infile);
    while(true){
        cout<<"enter word to look for, or q to quit: ";
        string s;
        if(!(cin>>s) || s == "q"){
            break;
        }
        print(cout, tq.query(s))<<endl;
    }
}

int main(){
    ifstream file("12.27.txt");
    runQueries(file);

    return 0;
}
运行结果显示如下

C++ //练习 12.30 定义你自己版本的TextQuery和QueryResult类,并执行12.3.1节(第431页)中的runQueries函数。-LMLPHP

04-22 14:16