文章目錄
- 使用標準庫:文本查詢程序
- 文本查詢程序設計
- 數據結構
- 在類之間共享數據
- 自己的文本查詢程序
- 書中的文本查詢程序
使用標準庫:文本查詢程序
我們將實現一個簡單的文本查詢程序,作為標準庫相關內容學習的總結。
我們的程序允許用戶在一個給定文件中查詢單詞。查詢結果是單詞在文件中出現的次數及其所在行的列表。如果一個單詞在一行中出現多次,此行只列出一次。行會按照升序輸出。
文本查詢程序設計
數據結構
我們定義一個保存輸入文件的類,將這個類命名為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