我有一个像这样的boost multi_index容器:

typedef multi_index_container<
    MyData,
        indexed_by<
            random_access<>,  // keep insertion order
            ordered_non_unique< member<MyData, time_t, &MyData::timestamp> >
        >
> myContType;

typedef myContType::nth_index<1>::type myContType_by_time;

和搜索方法:
unsigned long searchByTimestamp(time_t timestamp)
{

    myContType_by_time& idIndex = myCont.get<1>();
    myContType_by_time::iterator itTime = idIndex.find(timestamp);

    if (itTime == idIndex.end())
        return 0;

    // change the index from timestamp to insertionoder(id)
    myContType::const_iterator itId = myCont.project<0>(itTime);

    return itTime->id;
}

我使用timestamp(get<1> index)进行搜索,并且它起作用了,但是它从第一个(最早的)数据开始搜索。我想根据插入顺序(get<0> index)从最后添加的(最新)数据开始执行此操作。我尝试了该代码,但是没有用。
myCont.rearrange(get<0>(myCont).rbegin());

第一个问题:是否有一种方法可以从最后输入的数据开始搜索(根据插入顺序而不是时间戳,我的意思是get 索引)

第二个问题:如果找到的数据不是我想要的数据,如何从当前位置/索引继续搜索?我的意思是有没有像find_next这样的方法? (我在文档中找不到)

我正在使用Boost版本1.47.0开发Visual Studio 2008。

谢谢。

最佳答案

您可能应该只使用std::find中的<algorithm>,以及第一个索引中的反向迭代器:

unsigned long searchByTimestamp(Time_t timestamp)
{
    auto& idIndex = myCont.get<0>();

    auto itTime = std::find_if(
                idIndex.rbegin(), idIndex.rend(),
                [=](MyData const& item) { return item.timestamp == timestamp; }
            );

    if (itTime == idIndex.rend())
        return 0;

    return itTime->id;
}

注意:如果要将反向迭代器“投影”到(正向)迭代器,请在反向迭代器上使用.base()

看到它 Live On Coliru

现在,我真的不知道您需要continue searching from the "current" position的功能是什么(我的意思是,找到返回匹配项或rend()的内容,因此就没有继续了)。但是,否则,您可以做类似的事情(也可以查看 Live On Coliru :)
unsigned long searchByTimestamp(Time_t timestamp)
{
    auto& idIndex = myCont.get<0>();

    auto current = std::find_if(idIndex.rbegin(), idIndex.rend(),
            [=](MyData const& item) { return item.timestamp >= timestamp; });

    if (current != idIndex.rend())
    {
        bool some_extra_condition = current->timestamp == timestamp; // exact match?

        if (some_extra_condition)
            return current->id; // we have an exact match
    } else
    {
        // otherwise look for the next item that has an id divisible by 3 (3,6,9,...)
        auto alternative = std::find_if(current, idIndex.rend(),
            [=](MyData const& item) { return (item.id % 3) == 0; });

        if (alternative != idIndex.rend())
            return alternative->id;
    }

    return 0;
}

我完全构成了“替代”匹配谓词的愚蠢示例。如您所见,这都是常规STL算法的用法。这是可能的,因为算法是通过迭代器与容器分离的。

完整代码
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>

using namespace boost::multi_index;
static int idgen = 0;

enum Time_t { last_month, last_week, yesterday, today, tomorrow };
std::ostream& operator<<(std::ostream& os, Time_t tt) {
    switch(tt)
    {
        case last_month: return os << "last_month";
        case last_week:  return os << "last_week";
        case yesterday:  return os << "yesterday";
        case today:      return os << "today";
        case tomorrow:   return os << "tomorrow";
        default: return os << "?";
    };
}

struct MyData
{
    int id = ++idgen;

    MyData(Time_t timestamp) : timestamp(timestamp) {}
    Time_t timestamp;

    friend std::ostream& operator<<(std::ostream& os, MyData const& md)
    {
        return os << "(id:" << md.id << ", timestamp:" << md.timestamp << ")";
    }
};

typedef multi_index_container<
    MyData,
        indexed_by<
            random_access<>,  // keep insertion order
            ordered_non_unique< member<MyData, Time_t, &MyData::timestamp> >
        >
> myContType;

typedef myContType::nth_index<1>::type myContType_by_time;

myContType myCont;

unsigned long searchByTimestamp(Time_t timestamp)
{
    auto& idIndex = myCont.get<0>();

    auto itTime = std::find_if(
                idIndex.rbegin(), idIndex.rend(),
                [=](MyData const& item) { return item.timestamp == timestamp; }
            );

    if (itTime == idIndex.rend())
        return 0;

    return itTime->id;
}

#include <iostream>

int main()
{
    myCont.emplace_back(Time_t(last_week));
    myCont.emplace_back(Time_t(tomorrow));
    myCont.emplace_back(Time_t(last_month));
    myCont.emplace_back(Time_t(yesterday));

    std::cout << "Insertion order:\n";
    for (auto const& item : myCont)
        std::cout << item << "\n";

    std::cout << searchByTimestamp(today)     << "\n";
    std::cout << searchByTimestamp(last_month) << "\n";
}

关于c++ - 反向搜索和Multi_Index容器中的find_next函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21677550/

10-11 23:18
查看更多