文字查詢程式c++primer12.32
標頭檔案StrBlob以及StrBlobPtr
//根據題目要求用自己定義的StrBlob來代替vector<string>來儲存輸入檔案
//可以更加安全的共享底層資料
#include<iostream>
#include<vector>
#include<string>
#include<memory>
#include<fstream>
using namespace std;
class StrBlob { //自定義管理動態vector<string>的類,可以讓其物件共享同一個data
friend class StrBlobPtr;
public:
typedef vector<string>::size_type size_type;
StrBlob() : data(make_shared<vector<string>>()) {}
StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}
~StrBlob() { cout << " ~ Blob success " << endl; }
size_type size() const { return data->size(); }
bool empty()const { return data->empty(); }
void push_back(const string &st) const { data->push_back(st); }
void pop_back() const;
string &front() const;
string &back() const;
StrBlobPtr begin();
StrBlobPtr end();
private:
shared_ptr<vector<string>> data;
void check(size_type t, const string &msg) const;
};
//檢查一個給定的索引值是否在合法範圍內
void StrBlob::check(size_type t, const string &msg) const {
if (t >= data->size())
throw out_of_range(msg);
}
void StrBlob::pop_back() const {
check(0, "pop back on empty StrBlob");
data->pop_back();
}
string & StrBlob::front() const {
check(0, "pop back on empty StrBlob");
return data->front();
}
string & StrBlob::back() const {
check(0, "pop back on empty StrBlob");
return data->back();
}
class StrBlobPtr { //為StrBlob提供保護,指向Blob的data防止我們訪問其可能產生的空懸指標
public:
//預設情況下StrBlobPtr指向data的第一個下標
StrBlobPtr() :curr(0) { }
StrBlobPtr(StrBlob &a, size_t sz = 0) :wptr(a.data), curr(sz) { }
~StrBlobPtr(){ cout << " ~ BlobPtr success " << endl; }
string &deref() const; //用來解引用
StrBlobPtr& incr();//用來遞增
bool operator != (const StrBlobPtr &x) { return this->curr != x.curr; }
private:
size_t curr;
//check要檢查指標指向的vector是否還存在
shared_ptr<vector<string>> check(size_t, const string&) const;
weak_ptr<vector<string>> wptr;
};
shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string &msg) const {
auto ret = wptr.lock();
if (!ret) {
throw runtime_error("unbound StrBlobPtr");
}
if (i >= ret->size()) {
throw out_of_range(msg);
}
return ret;
}
string & StrBlobPtr::deref() const {
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
StrBlobPtr& StrBlobPtr::incr() {
auto p = check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr StrBlob::begin() {
return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end() {
auto ret = StrBlobPtr(*this, data->size());
return ret;
}
標頭檔案TextQuery以及QueryResult
#include<iostream>
#include<vector>
#include<new>
#include<set>
#include<map>
#include<fstream>
#include<algorithm>
#include<memory>
#include<sstream>
#include<string>
#include<iterator>
#include<iterator>
#include"Blob.h"
using namespace std;
class QueryResult;
class TextQuery { //儲存輸入檔案
public:
using LineNo = vector<string>::size_type;
TextQuery();
TextQuery(ifstream &infile);
~TextQuery(){ cout << " ~ TextQuery success " << endl; }
QueryResult query(const string &s) const;//返回一個查詢結果
private:
map<string, shared_ptr<set<LineNo>>> result; //通過字串來查詢對應的行號
//shared_ptr<vector<string>> data;
StrBlob data;//按行儲存輸入的檔案
};
class QueryResult { //儲存查詢結果
friend ostream& print(ostream &os, QueryResult &qr);
public:
QueryResult(const string &s, StrBlob vec, shared_ptr<set<TextQuery::LineNo>> n) :
word(s),data(vec),nos(n){
}
~QueryResult(){ cout << " ~ QueryResult success " << endl; }
//以下三個是根據12.33題目要求擴充套件,暫時未用到
set<TextQuery::LineNo>::iterator begin() const { return nos->begin(); }
set<TextQuery::LineNo>::iterator end() const { return nos->end(); }
StrBlob get_file() const { return data; }
private:
string word;
//shared_ptr<vector<string>> data;
StrBlob data; //與TextQuery共享data資料
shared_ptr<set<TextQuery::LineNo>> nos;//儲存與給定單詞關聯的行號
};
TextQuery::TextQuery(ifstream &infile) : data(){
LineNo lineNo = 0;
for (string line; getline(infile, line); ++lineNo) {
data.push_back(line);
istringstream line_stream(line);
for (string lineword; line_stream >> lineword; ) {
auto &nos = result[lineword];
if (!nos) //當行號第一次出現時此指標為空
nos.reset(new set<LineNo>);//分配一個新的set
nos->insert(lineNo);
}
}
/*string text;
while (getline(infile, text)) {
data->push_back(text);
int n = data->size() - 1;
istringstream line(text);
string word;
while (line >> word) {
auto &lines = result[word];
if (!lines)
lines.reset(new set<LineNo>);
lines->insert(n);
}
}*/
}
QueryResult TextQuery::query(const string& s) const {
shared_ptr<set<TextQuery::LineNo>> nodata(make_shared<set<LineNo>>());
auto found = result.find(s);
if (found != result.end())
return QueryResult(s, data, found->second);
else
return QueryResult(s, data, nodata);
}
ostream& print(ostream &out, QueryResult &qr) {
out << qr.word << " occurs " << qr.nos->size() << (qr.nos->size() > 1 ? "time" : "times") << endl;
for (auto i : *qr.nos) {
StrBlobPtr p(qr.data, i);
out << "( line " << i + 1 << ")" << p.deref() << endl;
}
return out;
}
主函式
#include<iostream>
#include<vector>
#include<new>
#include<set>
#include<algorithm>
#include<memory>
#include<sstream>
#include<string>
#include"ClassTQ.h"
using namespace std;
void runQueries(ifstream &infile) {
TextQuery tq(infile);
string s;
while (cin >> s && s != "q") {
cout << "請輸入要查詢的字串或者輸入q來退出查詢:" << endl;
print(cout, tq.query(s));
}
}
int main() {
ifstream txt1;
txt1.open("1.txt", ios::in);
cout << "open 1.txt success" << endl;
runQueries(txt1);
txt1.close();
return 0;
}
相關文章
- c++11 文字查詢練手小程式C++
- Java 查詢和高亮Word文字Java
- 第十四篇:一個文字查詢程式的實現
- 程式查詢
- CAD如何進行文字查詢
- 七、Qt Creator實現文字查詢QT
- linux根據字尾查詢文字Linux
- WebView實現頁內文字查詢功能WebView
- pgrep 查詢程式的工具
- 如何抽取Oracle資料到文字文件進行查詢NAOracle
- openstack程式碼共享量查詢
- 多階BOM查詢程式碼
- SQL查詢的:子查詢和多表查詢SQL
- 海量資料相似度計算之simhash短文字查詢
- Python 查詢PDF中的指定文字並高亮顯示Python
- 查詢之折半查詢
- mysql-分組查詢-子查詢-連線查詢-組合查詢MySql
- mysql 標量子查詢和現金盤程式製作非法子查詢MySql
- 複雜查詢—子查詢
- 查詢——二分查詢
- 子查詢-表子查詢
- 查詢(1)--靜態查詢
- 查詢(2)--動態查詢
- windows根據程式號查詢程式目錄Windows
- row lock contention 阻塞程式查詢
- library cache lock 阻塞程式查詢
- library cache pin 阻塞程式查詢
- 求多階BOM查詢程式碼
- 查詢程式使用的cursor 數量
- MYSQL學習筆記25: 多表查詢(子查詢)[標量子查詢,列子查詢]MySql筆記
- 資料庫 - 連線查詢、巢狀查詢、集合查詢資料庫巢狀
- 離線查詢與線上查詢
- 【SQL查詢】集合查詢之INTERSECTSQL
- 查詢與排序02,折半查詢排序
- 向表中插入中文字元,查詢時亂碼問題字元
- 查詢
- #查詢演算法#【1】簡單查詢:順序、折半查詢演算法
- pgrep查詢正在執行的程式ID