查找所有在Boost排序 [英] Find All Sorted in Boost

查看:205
本文介绍了查找所有在Boost排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Boost网站上提供的示例: http ://www.boost.org/doc/libs/1_55_0/libs/multi_index/example/basic.cpp 我学习了如何使用迭代器通过索引获取元素。但是,我想获得所有匹配的一个索引,并按另一个排序。

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.

例如,在给定的示例中,我想获取名为John的所有员工,但将结果返回给我按年龄排序。到目前为止,当我通过名字,我被返回一个itertor第一次出现的约翰,等等,但没有命令,他们的方式返回除了插入记录的顺序。

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.

请帮助!

版本号:

/* 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;
}


推荐答案

有两种方法:

1:使用基于复合键(name,age):

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:对结果排序:

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;
  }
}

哪个更好? #1给出了期望的结果,而没有进一步的后处理,但是对索引的插入(稍微)较慢,因为比较标准比通过名称的平凡比较更昂贵。 #2具有后处理惩罚,但可以与除年龄以外的排序标准一起使用(#1,其中一个是在定义时间固定的第二个键)。

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).

这篇关于查找所有在Boost排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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