获取boost::multi_index容器的元素的秩

get the rank of an element of a boost::multi_index container

本文关键字:元素 index boost multi 获取      更新时间:2023-10-16

下面的代码显示了一个按顺序和顺序进行索引的multi_index容器。

在我的用例中,元素将主要通过索引进行搜索,如果存在,则会获得下一个元素(按顺序)。

我的问题是,如何获得所获得的下一个元素的秩(按顺序)?

#include <iostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/ranked_index.hpp>
#include <boost/multi_index/identity.hpp>
using namespace boost::multi_index;
typedef multi_index_container <
    int
  , indexed_by<
        sequenced<>
      , ordered_non_unique<identity<int>>
      , ranked_non_unique<identity<int>>
    >
> Ints;
int main() {
    Ints ints;
    auto & sequence=ints.get<0>();
    auto & order=ints.get<1>();
    sequence.push_back(2);
    sequence.push_back(-1);
    sequence.push_back(5);
    sequence.push_back(6);
    auto it = order.find(2);
    if (it!=order.end()) {
        std::cout
            << "next to "
            << *it
            << " by sequence is "
            << *(++(ints.project<0>(it)))
            << std::endl
        ;
        std::cout
            << "next to "
            << *it
            << " by order is "
            << *(++(ints.project<1>(it))) //++it is good too
            << std::endl
        ;
        std::cout
            << "rank of next by sequence is "
            // << ??? ints.rank<???>(???)
            << std::endl
        ;
        std::cout
            << "rank of next by order is "
            // << ??? ints.rank<???>(???)
            << std::endl
        ;
    }
}

@se的答案是完全有效的,但在线性时间内运行。如果您想要更好的性能,可以考虑将索引#0定义为random_access,将索引#1定义为ranked_non_unique(索引#2是多余的):

typedef multi_index_container <
    int
  , indexed_by<
        random_access<>
      , ranked_non_unique<identity<int>>
    >
> Ints;

这样你就可以写:

std::cout
    << "rank of next by sequence is "
    << ints.project<0>(it)-sequence.begin()+1 // O(1)
    << std::endl
;
std::cout
    << "rank of next by order is "
    << order.rank(it)+1 // O(log n)
    << std::endl
;

假设您希望在排序索引中有某种"index into"或"offset from begin":

if (it!=order.end()) {
    auto rank_of = [&](auto it) {
        return std::distance(sequence.begin(), ints.project<0>(it));
    };
    auto seq_next = std::next(seq_it);
    auto ord_next = std::next(it);
    if (seq_next!=sequence.end())
    {
        std::cout << "next to                     " << *it << " by sequence is " << *seq_next << std::endl;
        std::cout << "rank of next by sequence is " << rank_of(seq_next) << std::endl;
    }
    if (ord_next!=order.end())
    {
        std::cout << "next to                     " << *it << " by order is " << *ord_next << std::endl ;
        std::cout << "rank of next by order is    " << rank_of(ord_next) << std::endl;
    }
}

没有多态lambdas,您应该写出