c++_primer_exercise_1704

本文介绍了一种使用C++编程语言通过文件系统遍历和数据结构优化来查找特定书籍在多个商店的销售记录的方法。通过实现一个函数find_book,该方法能够高效地在给定的一系列交易文件中找到指定书籍在每个商店的销售情况,并返回一个包含这些信息的向量。同时,还提供了一个报告函数用于展示搜索结果。

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

Exercise 17.4:

/*****************************************************
 * IDE:  VS2010
 * FILE: find_book.cpp
 *****************************************************/
#include 
using std::tuple; using std::make_tuple;
using std::get;
#include 
using std::vector;
#include 
using std::string;
#include 
using std::equal_range; using std::sort;
#include 
using std::accumulate;
#include 
using std::istream; using std::ostream;
using std::cin; using std::cout; using std::endl;
#include 
using std::ifstream;

#include "Sales_data.h"

// matches has three members: an index of a store 
// and iterators into that store's vector
typedef tuple::size_type,		\
	          vector::const_iterator,	\
              vector::const_iterator> matches;

// files holds the transactions for every store
// find_book returns a vector with an entry for each store that sold the given book
vector find_book(const vector> &files, const string &book)
{
	vector ret;	// initially empty
	// for each store find the range of matching books, if any
	for (auto it = files.cbegin(); it != files.cend(); ++it)
	{
		// find the range of Sales_data that have the same ISBN
		auto found = equal_range(it->cbegin(), it->cend(), book, compare_isbn);
		if (found.first != found.second)	// this store has sales
		{
			ret.push_back(make_tuple(it - files.cbegin() + 1, found.first, found.second));
		}
	}
	return ret;	// empty if no matches found
}

void report_results(istream &in, ostream &os, 
	                const vector> &files)
{
	string s;	// book to look for
	while (in >> s)
	{
		vector trans = find_book(files, s);
		if (trans.empty())
		{
			cout << s << " not found in any stores" << endl;
			continue;	// get the next book to look for
		}
		for (vector::iterator store = trans.begin(); \
			 store != trans.end(); ++store)	// find every store with a sale
		{
			// get returns the specified member from the tuple in store
			os << "store " << get<0>(*store) << " sales: " \
			   << accumulate(get<1>(*store), get<2>(*store), Sales_data(s))
			   << endl;
		}
	}
}

vector build_store(const string &s)
{
	Sales_data item;
	vector ret;
	ifstream is(s);
	while (is >> item)
	{
		ret.push_back(item);
	}
	sort(ret.begin(), ret.end(), compare_isbn);
	return ret;
}

int main()
{
	string stores[] = {"./data/store1", "./data/store2", "./data/store3", "./data/store4"};
	// each element in files holds the transactions for a particular store
	vector> files;
	for (int cnt = 0; cnt != 4; ++cnt)
	{
		files.push_back(build_store(stores[cnt]));
	}
	report_results(cin, cout, files);

	return 0;
}



/*****************************************************
 * IDE:  VS2010
 * FILE: Sales_data.h
 *****************************************************/
#ifndef SALES_DATA_H
#define SALES_DATA_H

#include 
#include 

class Sales_data
{
	friend std::ostream &operator<<(std::ostream &os, const Sales_data &item);
	friend std::istream &operator>>(std::istream &is, Sales_data &item);
	friend bool operator==(const Sales_data &lhs, const Sales_data &rhs);
	friend bool operator!=(const Sales_data &lhs, const Sales_data &rhs);
	friend Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs);

public:
	// constructors
	Sales_data() : units_sold(0), revenue(0.0) { }
	Sales_data(const std::string &s) :
		book_no(s), units_sold(0), revenue(0.0) { }
	Sales_data(const std::string &s, unsigned int n, double price) :
		book_no(s), units_sold(n), revenue(price * n) { }
	
	std::string isbn() const { return book_no; }
	Sales_data &operator+=(const Sales_data &rhs);

private:
	std::string book_no;
	unsigned int units_sold;
	double revenue;

	// utility function
	double avg_price() const;
};

// non-member Sales_data operations
inline bool compare_isbn(const Sales_data &lhs, const Sales_data &rhs)
{
	return lhs.isbn() < rhs.isbn();
}

#endif



/*****************************************************
 * IDE:  VS2010
 * FILE: Sales_data.cpp
 *****************************************************/
#include "Sales_data.h"

#include 
using std::string;
#include 
using std::istream; using std::ostream;

//// utility function
double Sales_data::avg_price() const
{
	if (units_sold)
	{
		return revenue / units_sold;
	}
	else
	{
		return 0;
	}
}

//// non-member Sales_data operations
ostream &operator<<(ostream &os, const Sales_data &item)
{
	os << item.isbn() << " " << item.units_sold << " "
	   << item.revenue << " " << item.avg_price();
	return os;
}

istream &operator>>(istream &is, Sales_data &item)
{
	double price;	// no need to initialize; we'll read into price before we use it
	is >> item.book_no >> item.units_sold >> price;
	if (is)			// check that the inputs succeeded
	{
		item.revenue = item.units_sold * price;
	}
	else			// input failed: give the object the default state
	{
		item = Sales_data();
	}
	return is;
}


bool operator==(const Sales_data &lhs, const Sales_data &rhs)
{
	return lhs.isbn() == rhs.isbn() &&
		lhs.units_sold == rhs.units_sold &&
		lhs.revenue == rhs.revenue;
}

bool operator!=(const Sales_data &lhs, const Sales_data &rhs)
{
	return !(lhs == rhs);
}

// member binary operator: left-hand operand is bound to the implicit this pointer
// assumes that both objects refer to the same book
Sales_data &Sales_data::operator+=(const Sales_data &rhs)
{
	units_sold += rhs.units_sold;
	revenue += rhs.revenue;
	return *this;
}

// assume that both objects refer to the same book
Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs)
{
	Sales_data sum = lhs;	// copy data 
	sum += rhs;
	return sum;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值