Предположим, для каждого магазина имеется файл транзакций. Каждый из этих транзакционных файлов в магазине будет содержать все транзакции для каждой группы книг. Предположим также, что некая другая функция читает эти транзакционные файлы, создает вектор vector
для каждого магазина и помещает эти векторы в вектор векторов:
//
//
vector
Давайте напишем функцию, которая будет просматривать файлы в поисках магазина, продавшего заданную книгу. Для каждого магазина, у которого есть соответствующая транзакция, необходимо создать кортеж для содержания индекса этого магазина и двух итераторов. Индекс будет позицией соответствующего магазина в файлах, а итераторы отметят первую и следующую после последней записи по заданной книге в векторе vector
этого магазина.
Для начала напишем функции поиска заданной книги. Аргументами этой функции будет только что описанный вектор векторов и строка, представляющая ISBN книги. Функция будет возвращать вектор кортежей с записями по каждому магазину, где была продана по крайней мере одна заданная книга:
//
typedef tuple
vector
vector
//
//
//
vector
findBook(const vector
const string &book) {
vector
//
//
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; //
}
Цикл for
перебирает элементы вектора files
, которые сами являются векторами. В цикле for
происходит вызов библиотечного алгоритма equal_range()
, работающего как одноименная функция-член ассоциативного контейнера (см. раздел 11.3.5). Первые два аргумента функции equal_range()
являются итераторами, обозначающими исходную последовательность (см. раздел 10.1). Третий аргумент — значение. По умолчанию для сравнения элементов функция equal_range()
использует оператор <
. Поскольку тип Sales_data
не имеет оператора <
, передаем указатель на функцию compareIsbn()
(см. раздел 11.2.2).
Алгоритм equal_range()
возвращает пару итераторов, обозначающих диапазон элементов. Если книга не будет найдена, то итераторы окажутся равны, означая, что диапазон пуст. В противном случае первый член возвращенной пары обозначит первую соответствующую транзакцию, а второй — следующую после последней.
После создания вектора магазинов с соответствующей транзакцией эти транзакции необходимо обработать. В данной программе следует сообщить результаты общего объема продаж для каждого магазина, у которого была такая продажа:
void reportResults(istream ∈, ostream &os,
const vector
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) //
//
//