// 文本查询程序-My-继承、.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<sstream>
#include<memory>
#include<vector>
#include<string>
#include<set>
#include<map>
using namespace std;
class QueryResult
{
using size_type = vector<string>::size_type;
public:
QueryResult(const string &s, shared_ptr<vector<string>> d, shared_ptr<set<size_type>> l) :word(s), data(d), line(l) {}
friend ostream& operator<<(ostream &os, const QueryResult &qr);
const set<size_type> get_line()const { return *line; } //返回类型不能危害原数据!上下是否有别?
const shared_ptr<vector<string>> get_data() const { return data; }
private:
string word;
shared_ptr<vector<string>> data;
shared_ptr<set<size_type>> line;
};
ostream& operator<<(ostream &os, const QueryResult &qr)
{
os <<"Exexuting Query for: "<< qr.word << endl;
if (qr.line->size() > 0) //是否查到单词的行号?
{
for (auto &r : (*(qr.line)))
{
cout << "\t(line " << r+1 << ")" << qr.data->at(r) << endl;
}
}
return os;
}
class Text
{
using size_type= vector<string>::size_type;
public:
Text():data(make_shared<vector<string>>()),linenum(make_shared<map<string, set<size_type>>>()){}
Text(const string &s) :Text() { read_file(s); }
Text(const Text &t) :data(t.data), linenum(t.linenum) {}
Text& operator=(const Text &t)
{
auto tmp(t);
data.reset();
data = tmp.data;
linenum.reset();
linenum = tmp.linenum;
return *this;
}
QueryResult query(const string &s) const;
private:
shared_ptr<vector<string>> data;
shared_ptr<map<string, set<size_type>>> linenum;
void read_file(const string &s);
};
void Text::read_file(const string &s)
{
ifstream file(s);
if (!file)
{
cerr << s << endl;
//throw
}
else
{
string tmp_line;
size_type cor_line=0;
while (getline(file,tmp_line))
{
istringstream word(tmp_line);
string tmp;
while (word >> tmp)
{
(*linenum)[tmp].insert(cor_line);
}
data->push_back(tmp_line);
cor_line = cor_line + 1;
}
}
}
QueryResult Text::query(const string &s) const
{
if (linenum->find(s) == linenum->cend())
return QueryResult(s,data, nullptr);
else
{
auto line = make_shared<set<size_type>>(linenum->at(s));
return QueryResult(s, data, line);
}
}
class Query;
class Query_Base
{
friend class Query;
public:
protected:
virtual ~Query_Base() {};
using size_type = vector<string>::size_type;
private:
virtual QueryResult eval(const Text &t) const=0;
virtual string rep()const=0;
};
class Word_Query:public Query_Base
{
friend class Query;
Word_Query(const string &s) :word(s){}
QueryResult eval(const Text &t) const{return t.query(word);}
string rep()const{return word;}
string word;
};
class Query
{
public:
Query(const string &s) :query(new Word_Query(s)) {} //new 和 make_shared,在创建中有什么区别?make_shared的实现代码:std::shared_ptr<T>(new T(args...))(word_query的构造函数都是私有或保护的,不能使用make_shared!)
Query(const Query &q) :query(q.query), txt(q.txt) {}
Query& operator=(const Query &q)
{
auto tmp(q);
query.reset();
query = q.query;
txt = q.txt;
return *this;
}
QueryResult eval(const Text &t) const
{
return query->eval(t);
}
string rep() const
{
return query->rep();
}
Query set_text(const Text &t) { txt = t; return *this; } //重载函数的返回类型幽默人要求!
friend Query operator~(const Query &q);
friend Query operator&(const Query &l, const Query &r);
friend Query operator|(const Query &l, const Query &r);
friend ostream& operator<<(ostream &os,const Query &q);
private:
shared_ptr<Query_Base> query;
Query(shared_ptr<Query_Base> q) :query(q) {} //私有构造函数!
Text txt;
};
ostream& operator<<(ostream &os,const Query &q)
{
os << q.eval(q.txt);
return os;
}
class Not_Query :public Query_Base
{
friend Query operator~(const Query &q);
//Not_Query(const string &s) :word(s) {} //接口为Query类,所以不应该有构造函数!
Not_Query(const Query &q) :query(q) {}
QueryResult eval(const Text &t) const;
string rep()const{return "~(" + query.rep() + ")";}
//string word;
Query query;
};
inline Query operator~(const Query &q)
{
return shared_ptr<Query_Base>(new Not_Query(q)); //返回类型相同吗???使用指针初始化Query对象,但是其构造函数是私有啊?(Query原先为基类指针,指向andquery,现在改为指向notquery)
}
QueryResult Not_Query::eval(const Text &t) const
{
auto r = query.eval(t); //query指向Word_Query类!
auto line = r.get_line();
auto data = r.get_data();
auto ret_line = make_shared<set<size_type>>();
for (size_type i = 0; i < data->size(); ++i)
{
if (line.find(i) == line.cend())
{
ret_line->insert(i);
}
}
return QueryResult(rep(), data, ret_line);
}
class BinaryQuery :public Query_Base
{
protected:
BinaryQuery(const Query &l,const Query &r,const string &s):lh(l),rh(r),opSym(s){ }
string rep()const { return "(" + lh.rep() + " " + opSym + " " + rh.rep() + ")"; }
Query lh, rh;
string opSym;
};
class And_Query :public BinaryQuery //求交集!
{
friend Query operator&(const Query &l, const Query &r);
private:
And_Query(const Query &l, const Query &r) :BinaryQuery(l, r, "&") {}
QueryResult eval(const Text &t) const override
{
auto lh_line = lh.eval(t).get_line();
auto rh_line = rh.eval(t).get_line();
auto data = lh.eval(t).get_data();
auto ret_line = make_shared<set<size_type>>();
for (auto &r : lh_line)
{
for (auto &k : rh_line)
{
if (r == k)
{
ret_line->insert(r);
}
}
}
return QueryResult(rep(), data, ret_line);
}
};
inline Query operator&(const Query &l,const Query &r)
{
return shared_ptr<Query_Base>(new And_Query(l, r));
}
class Or_Query :public BinaryQuery //并集
{
friend Query operator|(const Query &l, const Query &r);
private:
Or_Query(const Query &l, const Query &r) :BinaryQuery(l, r, "|") {}
QueryResult eval(const Text &t) const override;
};
QueryResult Or_Query::eval(const Text &t) const
{
auto lh_line = lh.eval(t).get_line();
auto rh_line = rh.eval(t).get_line();
auto data = lh.eval(t).get_data();
for (auto &r : lh_line)// rh_line.insert(lh_line.begin(),lh_line.end());推荐返回set的迭代器,在本函数中创建ret_line!切记不可随意改变原始数据!
{
rh_line.insert(r);
}
return QueryResult(rep(), data, make_shared<set<size_type>>(rh_line));
}
inline Query operator|(const Query &l, const Query &r)
{
return shared_ptr<Query_Base>(new Or_Query(l, r));
}
int main()
{
string filename="C:\\Users\\winack\\Documents\\Visual Studio 2017\\Projects\\文本查询程序-My-继承、\\123.txt";
Text info(filename);
Query q = Query("is") & Query("the") | Query("have");
q.set_text(info);
cout << q;
q = Query("have"); //定义了拷贝赋值操作!
q.set_text(info);
cout << q;
system("pause");
return 0;
}
文本查询程序-My-类
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...