在c++primer上看见了一个使用标准库的例子,文本查询程序,所以将程序在vs上进行实现。
书上对类进行了高度的封装,使用了友元函数对输出函数进行重定义。
使用在构造函数后面加:的方式对成员变量参数进行赋值,减少了函数参数的传递
在query函数中直接return类的构造函数,避免了再次对函数继续宁赋值。
总体代码如下:
在这里插入代码片
#include<iostream>
# include<algorithm> //这个是sort的头文件
#include<vector>
#include<string>
#include<set>
#include<map>
#include<memory> //shared_ptr
#include<fstream>
#include<sstream> //istringstream
using namespace std;
using line_no = vector<string>::size_type;1 using 可以代替typdef,所以这里line_no是一个vector<string>类型的迭代器别名
class QueryResult;
class TextQuery
{
public:
TextQuery(ifstream&);
TextQuery();
~TextQuery();
QueryResult query(const string& sought) const;
private:
shared_ptr<vector<string>> file; // 输入文件
map<string, shared_ptr<set<line_no>>> wm;//这里wm中key是string类型,value是迭代器类型的vector
};
TextQuery::TextQuery()
{
}
TextQuery::TextQuery(ifstream& ls):file(new vector<string>)
{
string text;
while (getline(ls, text))//逐行读入文件
{
file->push_back(text);//将此行文本进行保存
int n = file->size() - 1;//当前的行号
istringstream line(text);//istringstream可以将当前字符串以空格为分界线转为单词
string word;
while (line>>word)//逐单词便利该行
{
auto &lines = wm[word];
if (!lines)//如果没有找到该单词所对应的指针(也就是说第一次遇到这个单词,此指针为空)
{
lines.reset(new set<line_no>);//reser将智能指针指向新的对象,将之前的对象进行释放
}
lines->insert(n);//将所有的单词的行号都进行插入
}
}
}
class QueryResult
{
public:
friend ostream& print(ostream&, QueryResult&);
QueryResult::QueryResult()
{
}
QueryResult(string s,shared_ptr<set<line_no>> p,shared_ptr<vector<string>> f):sought(s),lines(p),file(f){}
~QueryResult();
private:
string sought;
shared_ptr<set<line_no>> lines;
shared_ptr<vector<string>> file;
};
ostream &print(ostream &os, QueryResult &qr)
{
os << qr.sought << "occurs" << qr.lines->size() << " ";
for (auto num : *qr.lines)
{
os << "\t(line)" << num + 1 << " " << *(qr.file->begin()+ num) << endl;
}
return os;
}
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);
}
}
QueryResult::~QueryResult()
{
}
TextQuery::~TextQuery()
{
}
int main()
{
ifstream infile("test.txt");
if (!infile.is_open()) {
cout << " 未 成 功 打 开 文 件!!" << endl;
return -1;
}
TextQuery tr(infile);
const string str = "1";
QueryResult qu;
qu= tr.query(str);
print(cout,qu);
return 0;
}
test文件如下:
程序运行结果为: