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。