查找全部从小到升压 [英] Find All Sorted in Boost

查看:75
本文介绍了查找全部从小到升压的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用提供了Boost网站上的例子: HTTP ://www.boost.org/doc/libs/1_55_0/libs/multi_index/example/basic.cpp 我学会了怎么去使用迭代器的索引元素。不过,我想获得全部由一个索引由另一匹配和排序。

例如,在给定的例子,我想获得名为约翰所有的员工,但把结果返回给我按年龄排序。截至目前,当我的名字,我返回itertor到中第一次出现约翰,等等,但没有为他们回到英国,其中记录插入的顺序其他的方式

请帮帮忙!

培训相关code:

  / * Boost.MultiIndex的基本示例。
 *
 *版权所有2003-2008华金中号洛佩斯·穆尼奥斯。
 * boost软件许可证1.0版下分发。
 *(见所附文件LICENSE_1_0.txt或复制
 * http://www.boost.org/LICENSE_1_0.txt)
 *
 *请参阅http://www.boost.org/libs/multi_index图书馆主页。
 * /#如果!定义(NDEBUG)
#定义BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#定义BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#万一#包括LT&;升压/ multi_index_container.hpp>
#包括LT&;提升/ multi_index / member.hpp>
#包括LT&;提升/ multi_index / ordered_index.hpp>
#包括LT&;&算法GT;
#包括LT&;&iostream的GT;
#包括LT&;&迭代器GT;
#包括LT&;串GT;使用boost :: multi_index_container的;
使用空间boost :: multi_index;/ *雇员纪录保持它的ID,姓名和年龄* /员工结构
{
  INT ID;
  性病::字符串名称;
  INT年龄;  员工(INT ID_,标准::字符串名_,诠释时代_):身份证(ID _),姓名(名称_),年龄(年龄_){}  朋友的std :: ostream的&放大器;运营商的LT;≤(的std :: ostream的和放大器; OS,常量员工急症)
  {
    OS<< e.id<<<< e.name<<<< e.age<<的std :: ENDL;
    返回操作系统;
  }
};/ *访问employee_set的相应指标标记* /结构ID {}​​;
结构名{};
年龄结构{};/ *看到具体的编译器:使用member_offset的有关信息
 * BOOST_MULTI_INDEX_MEMBER
 * // *定义员工的的multi_index_container用以下指标:
 * - 根据员工:: INT排序的唯一索引,
 * - 按雇员::名称排序的非唯一索引,
 * - 根据员工的年龄::排序的非唯一索引。
 * /的typedef multi_index_container的<
  雇员,
  的indexed_by<
    ordered_unique<
      标签< ID>中BOOST_MULTI_INDEX_MEMBER(员工,INT ID)>中
    ordered_non_unique<
      标签<名称>,BOOST_MULTI_INDEX_MEMBER(员工,标准::字符串,名称)>中
    ordered_non_unique<
      标签<年龄>中BOOST_MULTI_INDEX_MEMBER(员工,INT,年龄)GT; >
> employee_set的;模板< typename的标签,类型名MultiIndexContainer>
无效print_out_by(
 常量MultiIndexContainer&安培; S,
 标签* = 0 / *修复了一个MSVC ++ 6.0的bug与隐函数模板参数parms * /

{
  / *获得由标签标记的索引的引用* /  常量类型名称的boost :: multi_index ::指数< MultiIndexContainer,标签> ::类型和放大器; I =
    获得<标记和GT(S);  的typedef typename的MultiIndexContainer :: value_type的value_type的;  / *转储的索引的元素来清点* /  性病::复制(i.begin(),i.end()的std :: ostream_iterator<&VALUE_TYPE GT;(STD ::法院));
}
诠释的main()
{
  employee_set的ES;  es.insert(员工(0,乔,31));
  es.insert(员工(1,罗伯特,27));
  es.insert(员工(2,约翰,40));  / *下一个插入将失败,因为存在与雇员
   *相同的ID
   * /  es.insert(员工(2,亚里士多德,2387));  es.insert(员工(3,伟业,20));
  es.insert(员工(4,约翰,57));  / *列出了ID,姓名和年龄*排序的员工/  性病::法院LT&;<按ID<<的std :: ENDL;
  print_out_by<&ID GT;(ES);
  性病::法院LT&;<的std :: ENDL;  性病::法院LT&;<按名称<<的std :: ENDL;
  print_out_by<名称>(ES);
  性病::法院LT&;<的std :: ENDL;  性病::法院LT&;<年龄<<的std :: ENDL;
  print_out_by<年龄>(ES);
  性病::法院LT&;<的std :: ENDL;  返回0;
}


解决方案

您可以做两种方法之一:

1:与基于索引取代第二索引复合键(姓名,年龄):

 的typedef multi_index_container的<
  雇员,
  的indexed_by<
    ordered_unique<
      标签< ID>中成员<员工,INT和放大器;员工:: ID>>中
    ordered_non_unique<
      标签<名称&gt ;,
      composite_key<
        雇员,
        会员<员工的std ::字符串,&安培;员工::名称&gt ;,
        会员<员工,INT和放大器;员工::年龄>
      >
    >中
    ordered_non_unique<
      标签<年龄>中成员<员工,INT和放大器;员工::年龄>>
  >
> employee_set的;诠释的main()
{
  employee_set的ES = {
    {0,约翰,31},{1,罗伯特,27},{2,约翰,57},
    {5,约翰,2387},{3,伟业,20},{4,约翰,40}};  为(自动p值= es.get<名称>()equal_range(约翰); p.first = p.second;!++ p.first){
    性病::法院LT&;< *(p.first);
  }
}

2:显示结果:

 模板< typename的迭代器>
的std ::矢量<的std ::的reference_wrapper<常量员工>>
sort_by_age(性病::对<迭代器,迭代指p)
{
  的std ::矢量<的std ::的reference_wrapper<常量员工>> V(p.first,p.second);
  的std ::排序(v.begin(),v.end()
    [](常量员工和放大器; E1,常量员工和放大器; E2){返回e1.age< e2.age;});
  返回伏;
}诠释的main()
{
  employee_set的ES = {
    {0,约翰,31},{1,罗伯特,27},{2,约翰,57},
    {5,约翰,2387},{3,伟业,20},{4,约翰,40}};  为(自动E:sort_by_age(es.get<名称>()equal_range(约翰))){
    性病::法院LT&;&LT,E;
  }
}

哪个更好? #1得到所需的结果,而不进一步后处理,但插入到索引为(略)慢作为比较标准是比名称纯比较昂贵。 #2具有后处理罚款,但能够以比年龄其他排序标准被用来(以#1,其中之一是所述第二密钥获取固定在定义的时间)。

Using the example provided on the Boost website: http://www.boost.org/doc/libs/1_55_0/libs/multi_index/example/basic.cpp I've learned how to get elements by an index using iterators. However, I would like to get all matched by one index and sorted by another.

For instance, in the given example, I would like to get all employees whose name is "John", but have the results returned to me ordered by age. As of right now, when I get by name, I am returned an itertor to the first occurance of "John," and so on, but there is no order to the way they were returned other than the order in which the records were inserted.

Please help!

Relevent code:

/* Boost.MultiIndex basic example.
 *
 * Copyright 2003-2008 Joaquin M Lopez Munoz.
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or copy at
 * http://www.boost.org/LICENSE_1_0.txt)
 *
 * See http://www.boost.org/libs/multi_index for library home page.
 */

#if !defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#endif

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

using boost::multi_index_container;
using namespace boost::multi_index;

/* an employee record holds its ID, name and age */

struct employee
{
  int         id;
  std::string name;
  int         age;

  employee(int id_,std::string name_,int age_):id(id_),name(name_),age(age_){}

  friend std::ostream& operator<<(std::ostream& os,const employee& e)
  {
    os<<e.id<<" "<<e.name<<" "<<e.age<<std::endl;
    return os;
  }
};

/* tags for accessing the corresponding indices of employee_set */

struct id{};
struct name{};
struct age{};

/* see Compiler specifics: Use of member_offset for info on
 * BOOST_MULTI_INDEX_MEMBER
 */

/* Define a multi_index_container of employees with following indices:
 *   - a unique index sorted by employee::int,
 *   - a non-unique index sorted by employee::name,
 *   - a non-unique index sorted by employee::age.
 */

typedef multi_index_container<
  employee,
  indexed_by<
    ordered_unique<
      tag<id>,  BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
    ordered_non_unique<
      tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>,
    ordered_non_unique<
      tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >
> employee_set;

template<typename Tag,typename MultiIndexContainer>
void print_out_by(
 const MultiIndexContainer& s,
 Tag* =0 /* fixes a MSVC++ 6.0 bug with implicit template function parms */
)
{
  /* obtain a reference to the index tagged by Tag */

  const typename boost::multi_index::index<MultiIndexContainer,Tag>::type& i=
    get<Tag>(s);

  typedef typename MultiIndexContainer::value_type value_type;

  /* dump the elements of the index to cout */

  std::copy(i.begin(),i.end(),std::ostream_iterator<value_type>(std::cout));
}


int main()
{
  employee_set es;

  es.insert(employee(0,"Joe",31));
  es.insert(employee(1,"Robert",27));
  es.insert(employee(2,"John",40));

  /* next insertion will fail, as there is an employee with
   * the same ID
   */

  es.insert(employee(2,"Aristotle",2387));

  es.insert(employee(3,"Albert",20));
  es.insert(employee(4,"John",57));

  /* list the employees sorted by ID, name and age */

  std::cout<<"by ID"<<std::endl;
  print_out_by<id>(es);
  std::cout<<std::endl;

  std::cout<<"by name"<<std::endl;
  print_out_by<name>(es);
  std::cout<<std::endl;

  std::cout<<"by age"<<std::endl;
  print_out_by<age>(es);
  std::cout<<std::endl;

  return 0;
}

解决方案

You can do it in one of two ways:

1: Replace the second index with an index based on a composite key of (name,age):

typedef multi_index_container<
  employee,
  indexed_by<
    ordered_unique<
      tag<id>,  member<employee,int,&employee::id>>,
    ordered_non_unique<
      tag<name>,
      composite_key<
        employee,
        member<employee,std::string,&employee::name>,
        member<employee,int,&employee::age>
      >
    >,
    ordered_non_unique<
      tag<age>, member<employee,int,&employee::age>>
  >
> employee_set;

int main()
{
  employee_set es={
    {0,"John",31},{1,"Robert",27},{2,"John",57},
    {5,"John",2387},{3,"Albert",20},{4,"John",40}};

  for(auto p=es.get<name>().equal_range("John");p.first!=p.second;++p.first){
    std::cout<<*(p.first);
  }
}

2: Sort the results:

template<typename Iterator>
std::vector<std::reference_wrapper<const employee>>
sort_by_age(std::pair<Iterator,Iterator> p)
{
  std::vector<std::reference_wrapper<const employee>> v(p.first,p.second);
  std::sort(v.begin(),v.end(),
    [](const employee& e1,const employee& e2){return e1.age<e2.age;});
  return v;
}

int main()
{
  employee_set es={
    {0,"John",31},{1,"Robert",27},{2,"John",57},
    {5,"John",2387},{3,"Albert",20},{4,"John",40}};

  for(auto e:sort_by_age(es.get<name>().equal_range("John"))){
    std::cout<<e;
  }
}

Which is better? #1 gives the desired result without further postprocessing, but insertions into the index are (slightly) slower as the comparison criterion is more expensive than plain comparison by names. #2 has the postprocessing penalty, but can be used with sorting criteria other than age (with #1, which one is the second key gets fixed at definition time).

这篇关于查找全部从小到升压的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆