3

为了说明我的问题,我从 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"));

但是,如果我需要计算姓氏是“White”的人数,然后继续找出有多少“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);

或者有没有更聪明的方法来做到这一点?不仅从方便的角度来看,而且从性能的角度来看。

4

1 回答 1

3

因为phonebook有一个复合键,所以它按姓氏中的给定名称排序。std::equal_range因此,您可以在第一个搜索结果中调用常规来匹配仅定义了“Dorothy”的虚拟对象: 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"; 
   });
}

将为“White, Dorothy”打印电话号码 1 和 5 的实时示例。

于 2013-07-19T20:42:09.360 回答