C++Primer U15 面向对象程序设计完整代码

回头有时间再加上注释

#include <bits/stdc++.h>
#include "query_base.h"
using namespace std;

int main(void) {
	ifstream in("test.txt");
	new_runQueries(in);
	return 0;
}
#include <bits/stdc++.h>
#ifndef QUERY_BASE_H
#define QUERY_BASE_H

using namespace std;
class QueryResult;

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

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

TextQuery::TextQuery(ifstream &infile) : file(new vector<string>){
	string text;
	while(getline(infile, 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{
public:
	friend ostream& print(ostream&, const QueryResult&);
	using line_no = vector<string>:: size_type;
	QueryResult(const shared_ptr<vector<string>> &f,const string &w, const shared_ptr<set<line_no>> &l) : 
		file(f), word(w), lines(l){}
	std::set<TextQuery::line_no>::iterator
    begin() { return lines->begin(); }

    std::set<TextQuery::line_no>::iterator
    end()   { return lines->end();   }

	shared_ptr<vector<string>> get_file() const {return file;}
	void test_lines() {for (auto n : *lines) cout << n << endl;}
private:
	shared_ptr<vector<string>> file;
	string word;
	shared_ptr<set<line_no>> lines;
};

QueryResult TextQuery::query(const string & s) const{
	static shared_ptr<set<line_no>> line_empty(new set<line_no>);
	if (wm.find(s) == wm.end())
		return QueryResult(file, s, line_empty);
	return QueryResult(file, s, wm.at(s));
}

ostream& print(ostream& os, const QueryResult& que){
	int n = que.lines -> size();
	os << "element occurs " << n << " times" << endl;
	for (auto num : *que.lines){
		os << "    (line " << num + 1 << ") " << *(que.file -> begin() + num) << endl; 
	}
	return os;
}

class Query_base{
public:
    friend class Query;
protected:
    using line_no = TextQuery::line_no;
    virtual ~Query_base() = default;
private:
    virtual QueryResult eval(const TextQuery &tq) const = 0;
    virtual string rep() const = 0;
};

class Query{
public:
    friend Query operator~ (const Query&);
    friend Query operator| (const Query&, const Query&);
    friend Query operator& (const Query&, const Query&);
    Query (const string&);
    QueryResult eval(const TextQuery&t) const {return q -> eval(t);}
    string rep() const {return q -> rep();}
	void empty() {q = nullptr;}
private:
    Query(shared_ptr<Query_base> query) : q(query) {}
    shared_ptr<Query_base> q;
};

ostream& operator<<(ostream &os, const Query &q){
    return os << q.rep();
}

class WordQuery : public Query_base{
    friend class Query;
    WordQuery(const string &s) : query_word(s) {}
    QueryResult eval(const TextQuery &tq) const {return tq.query(query_word);}
    string rep() const {return query_word;}
    string query_word;
};

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

class NotQuery : public Query_base{
    friend class Query;
    friend Query operator~ (const Query&);
    NotQuery(const Query &q) : query(q) {}
    QueryResult eval(const TextQuery &tq) const;
    string rep() const {return "~(" + query.rep() + ")";}
    Query query;
};

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

class BinaryQuery : public Query_base{
protected:
	BinaryQuery(const  Query &l, const Query &r, string s) : lhs(l), rhs(r), op(s) {}
	Query lhs, rhs;
	string op;
	string rep() const {return "(" + lhs.rep() + op + rhs.rep() + ")";}
};

class AndQuery : public BinaryQuery{
	friend Query operator& (const Query&, const Query&);
	AndQuery(const Query &l, const Query &r) : BinaryQuery(l, r, "&") {}
	QueryResult eval(const TextQuery &tq) const;
};

inline 
Query operator& (const Query& q1, const Query& q2){
	return shared_ptr<Query_base>(new AndQuery(q1, q2));
}

class OrQuery : public BinaryQuery{
	friend Query operator| (const Query&, const Query&);
	OrQuery(const Query &l, const Query &r) : BinaryQuery(l, r, "|") {}
	QueryResult eval(const TextQuery &tq) const;
};

inline 
Query operator| (const Query& q1, const Query& q2){
	return shared_ptr<Query_base>(new OrQuery(q1, q2));
}

QueryResult OrQuery::eval(const TextQuery &tq) const{
	auto right = rhs.eval(tq);
	auto left = lhs.eval(tq);
	auto ret_lines = make_shared<set<line_no>>(left.begin(), left.end());
	ret_lines -> insert(right.begin(), right.end());
	return QueryResult(left.get_file(), rep(), ret_lines);
}

QueryResult AndQuery::eval(const TextQuery &tq) const{
	auto right = rhs.eval(tq);
	auto left = lhs.eval(tq);
	auto ret_lines = make_shared<set<line_no>>();
	set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines -> begin()));
	return QueryResult(left.get_file(), rep(), ret_lines);
}

QueryResult NotQuery::eval(const TextQuery &tq) const{
	auto result = query.eval(tq);
	auto ret_lines = make_shared<set<line_no>>();
	auto beg = result.begin(), end = result.end();
	auto sz = result.get_file() -> size();
	for (int i = 0; i < sz; i++){
		if (beg == end || *beg != i)
			ret_lines -> insert(i);
		else
			beg++;
	}
	return QueryResult(result.get_file(), rep(), ret_lines);
}

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

void new_runQueries(ifstream &infile){
	while (true){
		infile.clear();
		infile.seekg(0);
		cout << "enter word to look for" << endl;
		string s;
		if (!(getline(cin, s)) || s == "_q")
			break;
		vector<string> words;
		istringstream line(s);
		string word;
		while(line >> word){
			words.push_back(word);
		}
		int n = words.size();
		auto q = words[0] == "~" ? ~Query(words[0]) : Query(words[0]);
		int i =  words[0] == "~" ? : 1;
		for (; i < n - 1; i+=2){
			if (words[i + 1] != "~"){
				if (words[i] == "&"){
					q = q & Query(words[i + 1]);
				}
				else if (words[i] == "|"){
					q = q & Query(words[i + 1]);
				}
				else{
					cerr << "error1" << endl;
				}
			}
			else{
				if (words[i] == "&"){
					q = q & (~Query(words[i + 2]));
				}
				else if (words[i] == "|"){
					q = q | (~Query(words[i + 2]));
				}
				else{
					cerr << "error2" << endl;
				}
				i++;
			}
		}
		auto ans = q.eval(infile);
		print(cout, ans) << endl;
	}
}
#endif
  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值