文章目录
- 使用标准库:文本查询程序
- 文本查询程序设计
- 数据结构
- 在类之间共享数据
- 自己的文本查询程序
- 书中的文本查询程序
使用标准库:文本查询程序
我们将实现一个简单的文本查询程序,作为标准库相关内容学习的总结。
我们的程序允许用户在一个给定文件中查询单词。查询结果是单词在文件中出现的次数及其所在行的列表。如果一个单词在一行中出现多次,此行只列出一次。行会按照升序输出。
文本查询程序设计
数据结构
我们定义一个保存输入文件的类,将这个类命名为TextQuery,它包含一个vector和一个map。vector用来保存输入文件的文本,map用来关联每个单词和它出现的行号的set。这个类将会有一个用来读取给定输入文件的构造函数和一个执行查询的操作。
在类之间共享数据
自己的文本查询程序
TextQuery类
#ifndef __TEXTQUERY__
#define __TEXTQUERY__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
#include<fstream>
#include<sstream>
#include"QueryResult.h"
using namespace std;class TextQuery {
public:TextQuery() {}TextQuery(ifstream &ifs);QueryResult query(string & s);
private:shared_ptr<vector<string>>strText;shared_ptr<map<string,set<int>>>strNum;
};TextQuery::TextQuery(ifstream &ifs) {string str;vector<string>vec;while (getline(ifs, str)) {vec.push_back(str);}strText = make_shared<vector<string>>(vec);map<string, set<int>>mp;int LineNum = 1;for (auto a : *strText) {istringstream vecStr(a);string tmp;while (vecStr >> tmp) {mp[tmp].insert(LineNum);}LineNum++;}strNum = make_shared<map<string, set<int>>>(mp);cout << "success1"<<endl;
}QueryResult TextQuery::query(string & s) {if (strNum->find(s) == strNum->cend()) {return QueryResult(s, 0, strText, strNum);}int num = (strNum->at(s)).size();cout << "num:"<<num << endl;return QueryResult(s,num, strText, strNum);
}#endif
QueryResult类
#ifndef __QUERYRESULT__
#define __QUERYRESULT__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
using namespace std;class QueryResult {
public:QueryResult() {}QueryResult(string&s,int num,shared_ptr<vector<string>>strText, shared_ptr<map<string, set<int>>>strNum):str(s),nums(num),strText(strText),strNum(strNum){}string getStr() { return str; }int getNums() { return nums; }shared_ptr<vector<string>> getStrText() { return strText; }shared_ptr<map<string, set<int>>>getStrNum() { return strNum; }
private:string str;int nums;shared_ptr<vector<string>>strText;shared_ptr<map<string, set<int>>>strNum;
};ostream & print(ostream &os, QueryResult &qr) {if (qr.getNums() == 0) {os << qr.getStr() << " occurs " << qr.getNums() << " time" << endl;return os;}os << qr.getStr() << " occurs " << qr.getNums() << (qr.getNums() > 1 ? "times" : "time") << endl;shared_ptr<map<string, set<int>>> mp = qr.getStrNum();shared_ptr<vector<string>>vec = qr.getStrText();set<int>st=mp->at(qr.getStr());for (auto n:st) {os << "(line" << n << ")" << vec->at(n-1) << endl;}return os;}#endif
测试程序:
void testTextQuery() {ifstream infile("test.txt");TextQuery tq(infile);while (true) {cout << "enter word to look for,or q tu quit:"<<endl;string s;if (!(cin >> s) || s == "q")break;print(cout, tq.query(s)) << endl;}
}
书中的文本查询程序
TextQuery类
#ifndef __TEXTQUERY__
#define __TEXTQUERY__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
#include<fstream>
#include<sstream>
#include"QueryResult.h"
using namespace std;class TextQuery {
public:using line_no = vector<string>::size_type;TextQuery() {}TextQuery(ifstream &ifs);QueryResult query(const string & s)const;
private:shared_ptr<vector<string>>strText;map<string, shared_ptr<set<line_no>>>strNum;
};TextQuery::TextQuery(ifstream &ifs):strText(new vector<string>) {string str;while (getline(ifs, str)) {strText->push_back(str);int n = strText->size() - 1;istringstream vecStr(str);string word;while (vecStr >> word) {auto &lines = strNum[word];//lines是一个shared_ptrif (!lines)//在我们第一次遇到这个单词时,此指针为空lines.reset(new set<line_no>);//分配一个新的setlines->insert(n);}}
}QueryResult TextQuery::query(const string & s)const {static shared_ptr<set<line_no>>nodata(new set<line_no>);if (strNum.find(s) == strNum.cend()) {return QueryResult(s,strText, nodata);}elsereturn QueryResult(s,strText, strNum.find(s)->second);
}#endif
QueryResult类
#ifndef __QUERYRESULT__
#define __QUERYRESULT__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
using namespace std;class QueryResult {friend ostream& print(ostream &os, const QueryResult &qr);
public:using line_no = vector<string>::size_type;QueryResult() {}QueryResult(const string&s,shared_ptr<vector<string>>strText, shared_ptr<set<line_no>>strNum):str(s),strText(strText),strNum(strNum){}private:string str;shared_ptr<vector<string>>strText;shared_ptr<set<line_no>>strNum;
};ostream & print(ostream &os, const QueryResult &qr) {os << qr.str << " occurs " << qr.strNum->size()<< (qr.strNum->size() > 1 ? " times" : " time") << endl;for (auto n:*qr.strNum) {os << "\t(line" << n+1 << ")" << qr.strText->at(n) << endl;}return os;}#endif