加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

temp

发布时间:2020-12-16 10:46:31 所属栏目:百科 来源:网络整理
导读:QueryResult.h、TextQuery.h、TextQuery.cpp 和 make_plural.h 同练习 12.27。 Query.h #ifndef TEST_QUERY_H#define TEST_QUERY_H#include "TextQuery.h"#include string#include set#include iostream#include fstream#include sstream#include memory// a

QueryResult.h、TextQuery.h、TextQuery.cpp 和 make_plural.h 同练习 12.27。

Query.h

#ifndef TEST_QUERY_H
#define TEST_QUERY_H

#include "TextQuery.h"
#include <string>
#include <set>
#include <iostream>
#include <fstream>
#include <sstream>
#include <memory>

// abstract class acts as a base class for concrete query types; all members are private
class Query_base {
    friend class Query;

protected:
    typedef TextQuery::line_no line_no; // used in the eval functions
    virtual ~Query_base() {}

private:
    // eval returns the QueryResult that matches this Query
    virtual QueryResult eval(const TextQuery &) const = 0;

    // rep is a string representation of the query
    virtual std::string rep() const = 0;
};

// interface class to manage the Query_base inheritance hierarchy
class Query {
    // these operators need access to the shared_ptr constructor
    friend Query operator~(const Query &);

    friend Query operator|(const Query &,const Query &);

    friend Query operator&(const Query &,const Query &);

public:
    Query(const std::string &);  // builds a new WordQuery

    // interface functions: call the corresponding Query_base operations
    QueryResult eval(const TextQuery &t) const { return q->eval(t); }

    std::string rep() const { return q->rep(); }

private:
    Query(std::shared_ptr<Query_base> query) : q(query) {}

    std::shared_ptr<Query_base> q;
};

inline
std::ostream &
operator<<(std::ostream &os,const Query &query) {
    // Query::rep makes a virtual call through its Query_base pointer to rep()
    return os << query.rep();
}

class WordQuery : public Query_base {
    friend class Query; // Query uses the WordQuery constructor
    WordQuery(const std::string &s) : query_word(s) {}

    // concrete class: WordQuery defines all inherited pure virtual functions
    QueryResult eval(const TextQuery &t) const { return t.query(query_word); }

    std::string rep() const { return query_word; }

    std::string query_word;   // word for which to search
};

inline
Query::Query(const std::string &s) : q(new WordQuery(s)) {}

class NotQuery : public Query_base {
    friend Query operator~(const Query &);

    NotQuery(const Query &q) : query(q) {}

    // concrete class: NotQuery defines all inherited pure virtual functions
    std::string rep() const { return "~(" + query.rep() + ")"; }

    QueryResult eval(const TextQuery &) const;

    Query query;
};

class BinaryQuery : public Query_base {
protected:
    BinaryQuery(const Query &l,const Query &r,std::string s) :
            lhs(l),rhs(r),opSym(s) {}

    // abstract class: BinaryQuery doesn't define eval
    std::string rep() const {
        return "(" + lhs.rep() + " "
               + opSym + " "
               + rhs.rep() + ")";
    }

    Query lhs,rhs;    // right- and left-hand operands
    std::string opSym; // name of the operator
};

class AndQuery : public BinaryQuery {
    friend Query operator&(const Query &,const Query &);

    AndQuery(const Query &left,const Query &right) :
            BinaryQuery(left,right,"&") {}

    // concrete class: AndQuery inherits rep and defines the remaining pure virtual
    QueryResult eval(const TextQuery &) const;
};

class OrQuery : public BinaryQuery {
    friend Query operator|(const Query &,const Query &);

    OrQuery(const Query &left,"|") {}

    QueryResult eval(const TextQuery &) const;
};

inline Query operator&(const Query &lhs,const Query &rhs) {
    return std::shared_ptr<Query_base>(new AndQuery(lhs,rhs));
}

inline Query operator|(const Query &lhs,const Query &rhs) {
    return std::shared_ptr<Query_base>(new OrQuery(lhs,rhs));
}

inline Query operator~(const Query &operand) {
    return std::shared_ptr<Query_base>(new NotQuery(operand));
}

std::ifstream &open_file(std::ifstream &,const std::string &);

TextQuery get_file(int,char **);

bool get_word(std::string &);

bool get_words(std::string &,std::string &);

std::ostream &print(std::ostream &,const QueryResult &);

#endif //TEST_QUERY_H

Query.cpp

#include "Query.h"
#include "TextQuery.h"

#include <memory>
using std::shared_ptr;

#include <set>
using std::set;

#include <algorithm>
using std::set_intersection;

#include <iostream>
using std::ostream;

#include <cstddef>
using std::size_t;

#include <iterator>
using std::inserter;

#include <vector>
using std::vector;

#include <string>
using std::string;

// returns the lines not in its operand's result set
QueryResult
NotQuery::eval(const TextQuery &text) const {
    // virtual call to eval through the Query operand
    QueryResult result = query.eval(text);

    // start out with an empty result set
    shared_ptr<set<line_no> > ret_lines(new set<line_no>);

    // we have to iterate through the lines on which our operand appears
    QueryResult::line_it beg = result.begin(),end = result.end();

    // for each line in the input file,if that line is not in result,// add that line number to ret_lines
    vector<string>::size_type sz = result.get_file()->size();
    for (size_t n = 0; n != sz; ++n) {
        // if we haven't processed all the lines in result
        // check whether this line is present
        if (beg == end || *beg != n)
            ret_lines->insert(n);  // if not in result,add this line
        else if (beg != end)
            ++beg; // otherwise get the next line number in result if there is one
    }
    return QueryResult(rep(),ret_lines,result.get_file());
}

// returns the intersection of its operands' result sets
QueryResult
AndQuery::eval(const TextQuery &text) const {
    // virtual calls through the Query operands to get result sets for the operands
    QueryResult left = lhs.eval(text),right = rhs.eval(text);

    // set to hold the intersection of left and right
    shared_ptr<set<line_no> > ret_lines(new set<line_no>);

    // writes the intersection of two ranges to a destination iterator
    // destination iterator in this call adds elements to ret
    set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(*ret_lines,ret_lines->begin()));
    return QueryResult(rep(),left.get_file());
}

// returns the union of its operands' result sets
QueryResult
OrQuery::eval(const TextQuery &text) const {
    // virtual calls through the Query members,lhs and rhs
    // the calls to eval return the QueryResult for each operand
    QueryResult right = rhs.eval(text),left = lhs.eval(text);

    // copy the line numbers from the left-hand operand into the result set
    shared_ptr<set<line_no> >
            ret_lines(new set<line_no>(left.begin(),left.end()));

    // insert lines from the right-hand operand
    ret_lines->insert(right.begin(),right.end());
    // return the new QueryResult representing the union of lhs and rhs
    return QueryResult(rep(),left.get_file());
}

get_print.cpp

#include "Query.h"
#include "TextQuery.h"

#include <string>
using std::string;

#include <iostream>
using std::cout; using std::cin;

#include <fstream>
using std::ifstream;

#include <stdexcept>
using std::runtime_error;

// these functions are declared in Query.h
TextQuery get_file(int argc,char **argv) {
    // get a file to read from which user will query words
    ifstream infile;
    if (argc == 2)
        infile.open(argv[1]);
    if (!infile) {
        throw runtime_error("No input file!");
    }

    return TextQuery(infile);  // builds query map
}

bool get_word(string &s1) {
    cout << "enter a word to search for,or q to quit: ";
    cin >> s1;
    if (!cin || s1 == "q") return false;
    else return true;
}

bool get_words(string &s1,string &s2) {

    // iterate with the user: prompt for a word to find and print results
    cout << "enter two words to search for,or q to quit: ";
    cin >> s1;

    // stop if hit eof on input or a "q" is entered
    if (!cin || s1 == "q") return false;
    cin >> s2;
    return true;
}

and_orQueryTest.cpp

#include "Query.h"
#include "TextQuery.h"
#include <string>
#include <set>
#include <iostream>

using std::set;
using std::string;
using std::cin; using std::cout; using std::cerr;
using std::endl;

int main(int argc,char **argv)
{
    // gets file to read and builds map to support queries
    TextQuery file = get_file(argc,argv);

    // iterate with the user: prompt for a word to find and print results
    while (true) {
        string sought1,sought2,sought3;
        if (!get_words(sought1,sought2)) break;
        cout << "nenter third word: " ;
        cin  >> sought3;
        // find all the occurrences of the requested string
        Query q = Query(sought1) & Query(sought2)
                  | Query(sought3);
        cout << "nExecuting Query for: " << q << endl;
        const QueryResult results = q.eval(file);
        // report matches
        print(cout,results);
    }
    return 0;
}

运行程序前,在 CLion -> Run -> Edit Configurations 下配置 Program arguments 为 ../data

注:../data 即为文件 data 的文件名及其相对路径(是相对于可执行程序所在目录的相对路径)。

并在文件 data 中写入如下内容:

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

运行程序,程序执行结果如下所示:

// 运行结果
enter two words to search for,or q to quit: fiery bird

enter third word: wind

Executing Query for: ((fiery & bird) | wind)
((fiery & bird) | wind) occurs 3 times
    (line 2)Her Daddy says when the wind blows
    (line 4)like a fiery bird in flight.
    (line 5)A beautiful fiery bird,enter two words to search for,or q to quit: q

Process finished with exit code 0

下面是 andQueryTest.cpp 和 wordQueryTest.cpp 测试程序及其执行结果:

andQueryTest.cpp

#include "Query.h"
#include "TextQuery.h"

#include <string>
using std::string;

#include <iostream>
using std::cout; using std::endl;

#include <set>
using std::set;

int main(int argc,char **argv) {
    // gets file to read and builds map to support queries
    TextQuery file = get_file(argc,argv);

    do {
        string sought1,sought2;
        // stop if hit eof on input or a "q" is entered
        if (!get_words(sought1,sought2)) break;

        // find all the occurrences of the requested string
        Query andq = Query(sought1) & Query(sought2);
        cout << "nExecuting query for: " << andq << endl;
        QueryResult results = andq.eval(file);
        // report matches
        print(cout,results);

        results = Query(sought1).eval(file);
        cout << "nExecuted query: " << Query(sought1) << endl;
        // report matches
        print(cout,results);

        results = Query(sought2).eval(file);
        cout << "nExecuted query: " << Query(sought2) << endl;
        // report matches
        print(cout,results);
    } while (true);

    return 0;
}
// 运行结果
enter two words to search for,or q to quit: hair Alice

Executing query for: (hair & Alice)
(hair & Alice) occurs 1 time
    (line 1)Alice Emma has long flowing red hair.

Executed query: hair
hair occurs 2 times
    (line 1)Alice Emma has long flowing red hair.
    (line 3)through her hair,Executed query: Alice
Alice occurs 1 time
    (line 1)Alice Emma has long flowing red hair.
enter two words to search for,or q to quit: q

Process finished with exit code 0

wordQueryTest.cpp

#include "Query.h"
#include "TextQuery.h"
#include <string>
#include <vector>
#include <map>
#include <set>
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>

using std::set;
using std::string;
using std::map;
using std::vector;
using std::cerr;
using std::cout;
using std::cin;
using std::ifstream;
using std::endl;

int main(int argc,char **argv) {
    TextQuery file = get_file(argc,argv);

    // iterate with the user: prompt for a word to find and print results
    do {
        string sought;
        if (!get_word(sought)) break;

        // find all the occurrences of the requested string
        // define synonym for the line_no set 
        Query name(sought);
        const QueryResult results = name.eval(file);
        cout << "nExecuting Query for: " << name << endl;

        // report no matches
        print(cout,results) << endl;
    } while (true);  // loop indefinitely; the exit is inside the loop
    return 0;
}
// 运行结果
enter a word to search for,or q to quit: Daddy

Executing Query for: Daddy
Daddy occurs 3 times
    (line 2)Her Daddy says when the wind blows
    (line 7)"Daddy,"
    (line 10)Shyly,is there?"

enter a word to search for,or q to quit: q

Process finished with exit code 0

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读