Чтобы проиллюстрировать мой вопрос, я скопировал приведенный ниже код из примера «Телефонная книга» справочного документа Boost.
struct phonebook_entry
{
std::string family_name;
std::string given_name;
std::string ssn;
std::string phone_number;
}
И я могу сделать частичный поиск, как показано ниже
// search for Dorothea White's number
phonebook::iterator it=pb.find(boost::make_tuple("White","Dorothea"));
Однако, если мне нужно посчитать количество людей, у которых фамилия «Белый», а затем узнать, сколько «белых» имеют «Доротея» в качестве своего имени, то каков наилучший способ сделать это?
Я думаю, что я могу сделать два частичных запроса, с pb.find (boost :: make_tuple («White») и pb.find (boost :: make_tuple («White», «Dorothea»). Но я обеспокоен, приведет ли это к проблема с производительностью? Так как второй запрос не знает о первом запросе и просто выполняет поиск по всему контейнеру.
Предоставляет ли Boost что-то вроде ниже:
std::pair<iterator,iterator> partialResults=pb.equal_range("White");
std::pair<iterator, iterator> partialOfPartial=pb.equal_range("Dorothea", partialResults);
Или есть какой-нибудь умный способ сделать это? Не только с точки зрения удобства, но и для производительности.
Поскольку phonebook
имеет составной ключ, он сортируется по заданным именам в пределах фамилий. Так вы можете позвонить в std::equal_range
в первом результате поиска соответствовать манекен phonebook_entry
который определил только «Дороти»:
int main()
{
phonebook pb; // no initializer_list support for multi_index_container yet
pb.insert({ "White", "Dorothy", "1" });
pb.insert({ "Black", "Dorothy", "2" });
pb.insert({ "White", "John", "3" });
pb.insert({ "Black", "John", "4" });
pb.insert({ "White", "Dorothy", "5" });
auto const w = pb.equal_range("White");
auto const d = phonebook_entry{"", "Dorothy", ""};
auto const wd = std::equal_range(w.first, w.second, d, [](phonebook_entry const& lhs, phonebook_entry const& rhs) {
return lhs.given_name < rhs.given_name;
});
std::for_each(wd.first, wd.second, [](phonebook_entry const& pbe) {
std::cout << pbe.phone_number << "\n";
});
}
Живой пример это напечатает для «Белого, Дороти» номера телефонов 1 и 5.
Других решений пока нет …