C++ Primer(第五版) 17.1.1--17.1.2节练习

本文主要介绍了C++ Primer第五版中第17章的内容,涉及17.1到17.8节,重点讨论了如何使用tuple和pair实现不同功能,包括简单的操作和在复杂搜索结果中的应用。同时指出,对于更复杂的搜索结果处理,定义自定义类进行封装更为合适。此外,提到了Sales_data类的默认构造函数及其对isbn字段的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

17.1    

tuple<int, int, int> ti(10,, 20, 30);

17.2  

tuple<string, vector<string>, pair<string, int>> t;

17.3    使用tuple实现:

#ifndef	TEXTQUERY_H
#define	TEXTQUERY_H

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <memory>
#include <map>
#include <set>
#include <string>
#include <tuple>

using namespace std;

typedef vector<string>::size_type line_no;
typedef tuple<string, shared_ptr<set<line_no>>, shared_ptr<vector<string>>> QueryResult;

ostream &print(ostream &os, const QueryResult &qr);

class TextQuery {
public:
	TextQuery(ifstream&);
	QueryResult query(const string&) const;
private:
	shared_ptr<vector<string>> file;
	map<string, shared_ptr<set<line_no>>> wm;
};

TextQuery::TextQuery(ifstream &infile): file(make_shared<vector<string>>())
{
	string line;
	string word;
	line_no index = 0;
	
	while (getline(infile, line)) {
		file->push_back(line);
		++index;
		istringstream strline(line);
		while (strline >> word) {
			if (ispunct(word[0]))
				word.erase(0, 1);
			if (ispunct(word[word.size()-1]))
				word.pop_back();
			if (ispunct(word[word.size()-1]))
				word.pop_back();
			if (!wm[word])
				wm[word] = make_shared<set<line_no>>();
			wm[word]->insert(index);
		}
	}
}

QueryResult 
TextQuery::query(const string &s) const
{
	static shared_ptr<set<line_no>> nodata(make_shared<set<line_no>>());
	
	auto loc = wm.find(s);
	if (loc == wm.end())
		return QueryResult(s, nodata, file);
	else
		return QueryResult(s, loc->second, file);
}

inline
string make_plural(size_t ctr, const string &word, const string &ending)
{
	return (ctr > 1)? word + ending : word;
}

ostream &print(ostream &os, const QueryResult &qr)
{
	os << get<0>(qr) << " occurs " << get<1>(qr)->size() << " "
		<< make_plural(get<1>(qr)->size(), "time", "s") << endl;

	for (auto num : *(get<1>(qr)))
		os << "\t(line " << num << ") " << (*get<2>(qr))[num-1] << endl;

	return os;
}

#endif

17.4    使用tuple:

typedef tuple<vector<Sales_data>::size_type,
			  vector<Sales_data>::const_iterator,
			  vector<Sales_data>::const_iterator> matches;

vector<matches>
findBook(const vector<vector<Sales_data>> &files,
		 const string &book)
{
	vector<matches> ret;
	
	for (auto it = files.cbegin(); it != files.cend(); ++it) {
		auto found = equal_range(it->cbegin(), it->cend(), book, compareIsbn);
		if (found.first != found.second)
			ret.push_back(make_tuple(it - files.cbegin(), found.first, found.second));
	}
	
	return ret;
}

void reportResults(istream &in, ostream &os, const vector<vector<Sales_data>> &files)
{
	string s;
	
	while (in >> s) {
		auto trans = findBook(files, s);
		if (trans.empty()) {
			cout << s << "not found in any stores" << endl;
			continue;
		}
		for (const auto &store : trans)
			os << "store " << get<0>(store) << " sales: "
				<< accumulate(get<1>(store), get<2>(store), Sales_data(s)) << endl;
	}
}

17.5    使用pair:

typedef pair<vector<Sales_data>::size_type,
			 pair<vector<Sales_data>::const_iterator, vector<Sales_data>::const_iterator>> matches;

vector<matches>
findBook(const vector<vector<Sales_data>> &files,
		 const string &book)
{
	vector<matches> ret;
	
	for (auto it = files.cbegin(); it != files.cend(); ++it) {
		auto found = equal_range(it->cbegin(), it->cend(), book, compareIsbn);
		if (found.first != found.second)
			ret.push_back(make_pair(it - files.cbegin(), make_pair(found.first, found.second)));
	}
	
	return ret;
}

void reportResults(istream &in, ostream &os, const vector<vector<Sales_data>> &files)
{
	string s;
	
	while (in >> s) {
		auto trans = findBook(files, s);
		if (trans.empty()) {
			cout << s << "not found in any stores" << endl;
			continue;
		}
		for (const auto &store : trans)
			os << "store " << store.first << " sales: "
				<< accumulate(store.second.first, store.second.second, Sales_data(s)) << endl;
	}
}

17.6        定义一个类实现:

class matches {
public:
	matches(vector<Sales_data>::size_type n, 
			pair<vector<Sales_data>::const_iterator, vector<Sales_data>::const_iterator> t):
			num(n), first(t.first), last(t.second) { }
	vector<Sales_data>::size_type get_num() const { return num; }
	vector<Sales_data>::const_iterator get_first() const { return first; }
	vector<Sales_data>::const_iterator get_last() const { return last; }
private:
	vector<Sales_data>::size_type num;
	vector<Sales_data>::const_iterator first, last;
};

vector<matches>
findBook(const vector<vector<Sales_data>> &files,
		 const string &book)
{
	vector<matches> ret;
	
	for (auto it = files.cbegin(); it != files.cend(); ++it) {
		auto found = equal_range(it->cbegin(), it->cend(), book, compareIsbn);
		if (found.first != found.second)
			ret.push_back(matches(it - files.cbegin(), make_pair(found.first, found.second)));
	}
	
	return ret;
}

void reportResults(istream &in, ostream &os, const vector<vector<Sales_data>> &files)
{
	string s;
	
	while (in >> s) {
		auto trans = findBook(files, s);
		if (trans.empty()) {
			cout << s << "not found in any stores" << endl;
			continue;
		}
		for (const auto &store : trans)
			os << "store " << store.get_num() << " sales: "
				<< accumulate(store.get_first(), store.get_last(), Sales_data(s)) << endl;
	}
}

17.7    使用tuple和pair比较简单直接,如果要对搜索结果进行更复杂的处理,则定义一个类进行封装更好。

17.8    Sales_data()是默认构造函数,isbn被初始化为空字符串,在输出结果中无法看到书的isbn。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值