iT邦幫忙

3

C++ Primer 5th Edition Exercises(練習題)12.27改統用智慧指標shared_ptr來管理二個容器(container)

Exercises Section 12.3.1
Exercise 12.27: The TextQuery and QueryResult classes use only
capabilities that we have already covered. Without looking ahead, write your
own versions of these classes.

TextQuery和QueryResult類別會用到的功能並不會超出我們已經討論過的範圍。在繼續閱讀本書前,針對這兩個類別,先試著依照我們談過的功能寫出你自己版本的TextQuery和QueryResult。

https://play.google.com/books/reader?id=J1HMLyxqJfgC&pg=GBS.PT902
https://drive.google.com/open?id=140Kwtzv7xCWploxvSN41MHlHmXd4VUO-
臉書直播:
https://www.facebook.com/oscarsun72/videos/2569013886543063
約在 2:09:00處
瞧瞧當時成功時的驚喜若狂 呵呵
感恩感恩 讚歎讚歎 南無阿彌陀佛
Youtube實境秀:
Yes
相關文章

#include<iostream>
#include<memory>
#include <fstream>
#include"TextQuery.h"
#include"QueryResult.h"
using namespace std;
 
pair<shared_ptr<vector<string>>,shared_ptr<map<string,set<size_t>>>> queryData(ifstream& infile)
{
	string lStr;
	size_t line_Num{ 0 };
	vector<string>vs;//主要就是這兩個(vector、map)容器要作為TexQuery與QueryResult資源共享者
	map<string, set<size_t>>word_lineNum;
	shared_ptr<vector<string>>spVs(make_shared<vector<string>>(vs));//利用智慧指標shared_ptr來達到
	shared_ptr<map<string, set<size_t>>>spWord_lineNum(
		make_shared<map<string,set<size_t>>>(word_lineNum));//資源共用的目的
	while (infile && !infile.eof())//第98集6:46:00
	{
		getline(infile, lStr);
		spVs->push_back(lStr);//one line of text in an element		
		++line_Num;
		istringstream isstr(lStr);
		string word;		
		while (isstr >> word)
		{
			map<string, set<size_t>>::iterator mIter = spWord_lineNum->find(word);
			if (mIter == spWord_lineNum->end()) {//如果文字行號的map還沒有此文字的話
				set<size_t> line_num_st;
				line_num_st.insert(line_Num);
				spWord_lineNum->insert(make_pair(word, line_num_st));
			}
			else//如果文字行號的map已經有此文字的話
				mIter->second.insert(line_Num);//若原已有此行號,用insert就不會插入(何況set本來鍵值(就是「值」)就不能重複
		}
	}
	return make_pair(spVs,spWord_lineNum);
}
 
int main() {
	string fName,strSearch;
	cout << "請指定要檢索的檔案全名(fullname,含路徑與副檔名)" << endl;
	if (cin >> fName);
	//必須檢查檔案存不存在	
	else//若沒有指定檔案的話
	{
		fName = "V:\\Programming\\C++\\input.txt";
	}
	cin.clear();//cin前面已經移動它的迭代器(iterator)了到讀取失敗的位置,故要歸零清除,
	//否則如果這裡讀取失敗,後面的cin >> strSearch判斷就會永遠都是false(讀取失敗)了
	//第89集1:4:00//可參考前面談資料流(stream)的部分
	ifstream ifs(fName);
	TextQuery tq(queryData(ifs));
	while(true){
		cout << "請輸入檢索字串,或輸入「q」離開" << endl;
		if (!(cin >> strSearch) || strSearch == "q") break;
		QueryResult qr= tq.query(strSearch);
		qr.print();		
	}
}
#ifndef TextQuery_H
#define TextQuery_H
#include<vector>
#include<memory>
#include<iostream>
#include<fstream>
#include<sstream>
#include<string>//要用getline函式,要引入這一行
#include<map>
#include<set>
#include "QueryResult.h"
using namespace std;
class TextQuery
{
	friend class QueryResult;
	typedef pair<map<string, size_t>::const_iterator, map<string, size_t>::const_iterator>
		pair_iterator_map;
	typedef pair<shared_ptr<vector<string>>, shared_ptr<pair<string, set<size_t>>>> pair_sp_vec_str_sp_pair_str_set;
	using iterator_map= map<string, set<size_t>>::iterator;
public:
	//TextQuery() ;
	TextQuery(ifstream& infile);
	TextQuery(pair<shared_ptr<vector<string>>, shared_ptr<map<string, set<size_t>>>>spPair):
		spVs(spPair.first),word_lineNum(*spPair.second){};
	~TextQuery();
	QueryResult query(const string&);
private:
	shared_ptr<vector<string>>spVs;//第89集 2:12:00
	//一個map關聯式容器(associative container)因為一個字詞key(string)會有好幾行與之對應,故用
	//map,而其「值」為set容器
	map<string, set<size_t>>word_lineNum;
};
 
TextQuery::TextQuery(ifstream& infile)
{
	string lStr;
	size_t line_Num{ 0 };
	vector<string>vs;
	spVs = make_shared<vector<string>>(vs);
	while (infile && !infile.eof())//第89集2:4:00
	{
		getline(infile, lStr);
		spVs->push_back(lStr);//one line of text in an element		
		++line_Num;
		istringstream isstr(lStr);
		string word;
		while (isstr >> word)
		{
			map<string, set<size_t>>::iterator mIter = word_lineNum.find(word);			
			if (mIter == word_lineNum.end()) {//如果文字行號的map還沒有此文字的話
				set<size_t> line_num_st;
				line_num_st.insert(line_Num);
				word_lineNum.insert(make_pair(word, line_num_st));
			}
			else//如果文字行號的map已經有此文字的話
				mIter->second.insert(line_Num);//若原已有此行號,用insert就不會插入(何況set本來鍵值(就是「值」)就不能重複
		}
	}
}
 
 
TextQuery::~TextQuery()
{
 
}
 
QueryResult TextQuery::query(const string& wordForQuery)
{
	/*第88集4:18:23//4:31:30回傳的應該是檢索結果,
	 *(此行註文但作參考)或者試用allocator物件記錄在動態記憶體(dynamic memory),再與QueryResult物件共用此資料*/
	//臉書直播第443集、444集。第89集1:18:00
 
	iterator_map wlIter = word_lineNum.find(wordForQuery);
	if (wlIter == word_lineNum.end())
	{
		cout << "沒有找到您要找的字串!" << endl; 
		set<size_t>st;
		return QueryResult(make_shared<pair<string, set<size_t>>>
			(make_pair(wordForQuery,st)));//()呼叫運算子(call operator)這裡表示呼叫預設建構器(default constructor)
	}		
	//shared_ptr<pair<string, set<size_t>>> sp = make_shared<pair<string,set<size_t>>>(*wlIter);
	//QueryResult qrfound(spVs, sp);
	return QueryResult(spVs,make_shared<pair<string,set<size_t>>>(*wlIter));//「()」:呼叫建構器
#ifndef QueryResult_H
#define QueryResult_H
#include<vector>
#include<memory>
#include<iostream>
#include<iterator>
#include"TextQuery.h"
using namespace std;
class QueryResult
{
public:
	QueryResult(shared_ptr<pair<string,set<size_t>>>sp_key) :pair_str_set(sp_key) { found = false; }
	QueryResult(shared_ptr<vector<string>>, shared_ptr<pair<string, set<size_t>>>);
	~QueryResult();
	void print();
 
private:
	shared_ptr<vector<string>>vs;
	shared_ptr<pair<string, set<size_t>>>pair_str_set;
	bool found;
};
 
QueryResult::QueryResult(shared_ptr<vector<string>> sp_vec_str, shared_ptr<pair<string, set<size_t>>> sp_pair_str_set)
{
	vs = sp_vec_str;//這樣才是由智慧指標(smart pointer)來管理,而不是
	//vs=*sp_vec_str ←原來寫這樣,就是解參考智慧指標後再把解參考的結果容器,指定(即複製一份)
	//給「vs」這個資料成員;這樣就不合資源共享(共用資源)的原則,反而成複製一份了。第98集2:40:00
	pair_str_set = sp_pair_str_set;
	found = true;
}
 
QueryResult::~QueryResult()
{
}
 
inline void QueryResult::print()
{
	ostream_iterator<string>o(cout);
	ostream_iterator<size_t>o_size_t(cout);
	*o++ = pair_str_set->first;
	*o++ = " occurs ";
	if (!found)
		*o++ = "0 time";
	else//如果有找到
	{
		*o_size_t++ = pair_str_set->second.size();
		*o++ = (pair_str_set->second.size() > 1) ? " times" : " time";
		cout << endl;
		for (const size_t i : pair_str_set->second)
		{
			*o++ = "\t(line ";
			*o_size_t++ = i;
			*o++ = ")";
			*o++ = (*vs)[i - 1];
			cout << endl;
		}
	}
	cout << endl;
}
 
#endif // !QueryResult_H

https://github.com/oscarsun72/prog1-C-Primer-5th-Edition-s-Exercises/tree/exercise12_27with_shared_ptr/prog1

 

https://github.com/oscarsun72/prog1-C-Primer-5th-Edition-s-Exercises/branches

 

C++自修入門實境秀 508 重新譯撰 《C++ Primer 5th》
Chapter 12. Dynamic Memory
12.3 Using the Library: A Text-Query Program 12.3.1. Design of the Query Program
練習12.27 再複習12章,試用 allocator ,以動態配置的物件(dynamically allocated object)來改寫
上一集:
https://www.facebook.com/100003034306665/videos/2578200402291078
下一集:
緣起:http://bit.ly/2XwHOUH

全部:http://bit.ly/2NoA2ID 原檔下載:http://bit.ly/2Ixe2Vc
課文: http://bit.ly/2FIHV57
http://bit.ly/2mttmfa(第二篇)
第10章: http://bit.ly/2MuPmiZ
章12、13: http://bit.ly/2r7qSW7
重譯12章:http://bit.ly/2G2fPSg (docx) http://bit.ly/2V8UgZ7
重譯11章:http://bit.ly/39P7HRU

https://play.google.com/books/reader?id=J1HMLyxqJfgC&pg=GBS.PT902

講義下載:
http://bit.ly/2khF8Ic (全部)
程式碼:
https://github.com/oscarsun72/prog1
————————————————
版权声明:本文为CSDN博主「任真」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/oscarsun72/article/details/104446129


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言