做得很吐血...... #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <cstddef> #include <sstream> #include <fstream> #include <algorithm> #include <numeric> class TextQuery { typedef std::map<std::string, std::set<std::size_t> > Type; public: void read_file(const std::string &strPath) { get_data(strPath); } std::string get_str(std::size_t i) const; std::set<std::size_t> get_lines(const std::string &word); std::size_t size() const { return lines.size(); } private: void get_data(const std::string &strPath); private: std::vector<std::string> lines; Type words; }; void TextQuery::get_data(const std::string &strPath) { std::ifstream read(strPath.c_str()); if (!read) return; std::string str_line; std::size_t index = -1; while (std::getline(read, str_line)) { ++index; lines.push_back(str_line); std::istringstream str_word(str_line); std::string word; while ( str_word >> word) { words[word].insert(index); } } read.close(); } std::string TextQuery::get_str(std::size_t i) const { return lines[i]; } std::set<std::size_t> TextQuery::get_lines(const std::string &word) { return words[word]; } class Query_Base { friend class Query; protected: virtual ~Query_Base() { } private: virtual std::set<std::size_t> eval(TextQuery &text) = 0; virtual void display(std::ostream &os = std::cout) = 0; }; class WordQuery: public Query_Base { friend class Query; private: WordQuery(const std::string &str): word(str) { } virtual std::set<size_t> eval(TextQuery &text) { return text.get_lines(word); } virtual void display(std::ostream &os = std::cout) { os << word; } std::string word; virtual ~WordQuery() { } }; class Query { friend Query operator|(const Query &que1, const Query &que2); friend Query operator&(const Query &que1, const Query &que2); friend Query operator~(const Query &que); public: Query(const std::string &word): p(new WordQuery(word)), use(new std::size_t(1)) { } Query(const Query &query): p(query.p), use(query.use) { ++*use; } Query& operator=(const Query &query) { ++*use; del_use(); p = query.p; use = query.use; } std::set<std::size_t> eval(TextQuery &text) { return p->eval(text); } void display(std::ostream& os = std::cout) { p->display(os); } private: Query(Query_Base *base): p(base), use(new std::size_t(1)) { } Query_Base * p; std::size_t *use; void del_use() { if (--*use == 0) { delete p; delete use; } } }; std::ostream& operator<<(std::ostream& os, Query &que) { que.display(os); return os; } class NotQuery: public Query_Base { friend Query operator~(const Query &query); private: NotQuery(Query que):query(que) { } virtual std::set<std::size_t> eval(TextQuery &text); virtual void display(std::ostream &os /* = std::cout */) { os << "( ~" << query << " )"; } Query query; }; class BinaryQuery: public Query_Base { protected: BinaryQuery(Query lf, Query rh, std::string op): left(lf), right(rh), oper(op) { } virtual void display(std::ostream &os /* = std::cout */) { os << "( " << left << oper << right << " )"; } Query left; Query right; std::string oper; }; class AndQuery: public BinaryQuery { friend Query operator&(const Query &que1, const Query &que2); private: AndQuery(Query lf, Query rg): BinaryQuery(lf, rg, "&") {} virtual std::set<std::size_t> eval(TextQuery &text); }; class OrQuery: public BinaryQuery { friend Query operator|(const Query &que1, const Query &que2); private: OrQuery(Query lf, Query rg): BinaryQuery(lf, rg, "|") {} virtual std::set<std::size_t> eval(TextQuery &text); }; Query operator|(const Query &que1, const Query &que2) { return new OrQuery(que1, que2); } Query operator&(const Query &que1, const Query &que2) { return new AndQuery(que1, que2); } Query operator~(const Query &que) { return new NotQuery(que); } std::set<std::size_t> AndQuery::eval(TextQuery &text) { std::set<std::size_t> rg = right.eval(text), lft = left.eval(text); std::set<std::size_t> sum; std::set_intersection(rg.begin(), rg.end(), lft.begin(), lft.end(), std::inserter(sum, sum.end())); return sum; } std::set<std::size_t> OrQuery::eval(TextQuery &text) { std::set<std::size_t> rg = right.eval(text), lft = left.eval(text); lft.insert(rg.begin(), rg.end()); return lft; } std::set<std::size_t> NotQuery::eval(TextQuery &text) { std::set<std::size_t> word_line = query.eval(text), not_line; for (std::size_t i = 0; i != text.size(); ++i) { if (word_line.find(i) == word_line.end()) { not_line.insert(i); } } return not_line; } int main() { std::string strPath; std::cin >> strPath; TextQuery text; text.read_file(strPath); Query find = Query("timeout=3") | Query("[boot"); std::cout << find << std::endl; std::set<std::size_t> line = find.eval(text); for (std::set<std::size_t>::iterator iter = line.begin(); iter != line.end(); ++iter) { std::cout << "<line " << *iter << ">"<< text.get_str(*iter) << std::endl; } system("pause"); return 0; }