7
4

3 回答 3

6

你的boost::multi_index尝试几乎就在那里。问题是,当您使用有序索引进行查找时,迭代也是有序的。幸运的是,多索引提供了一种project在索引之间切换的机制。如果我正确阅读了文档:

auto ordered_iter = myMap.find(1001);
auto iter = boost::multi_index::project<0>(ordered_iter);
于 2014-02-06T16:58:39.040 回答
1

我会使用 amultimap<Key,List<Item>::Iterator>与 a 配对List<Item>。我会使用地图进行查找,列表将按插入顺序保存项目。您需要在所有插入/更新/删除方案中使两个容器保持最新。如果您可以详细说明您的用例,可能会有更好的选择。

此选项将为您提供 log(n) 查找,同时仍允许恒定时间删除索引和项目。这类似于我过去实现 LRU 缓存的方式。

由于问题而编辑

typedef list<myData> DataLst;
typedef DataLst::iterator LstIter; 
typedef multimap<unsigned long, LstIter> mpType; 

mpType BuildIndex(DataLst &lst)
{
    mpType ret; 
    for (auto Item = begin(lst); Item != end(lst); Item++)
    {       
        ret.insert(make_pair(Item->id,Item));
    }
    return ret; 
}

int _tmain(int argc, _TCHAR* argv[])
{
    DataLst myDataContainer; 
    myDataContainer.push_back(myData(1002, 1));
    myDataContainer.push_back(myData(1001, 2));
    myDataContainer.push_back(myData(1005, 3));
    myDataContainer.push_back(myData(1003, 4));
    myDataContainer.push_back(myData(1000, 5));

    auto myMap = BuildIndex(myDataContainer);
    auto iter = myMap.find(1001);
    cout << "The iter insert  = " << iter->second->insertionOrder << endl;
    cout << "The iter insert after = " <<  std::next(iter->second)->insertionOrder << endl;
    cout << "The iter insert before = " << std::prev(iter->second)->insertionOrder << endl;
    string foo; 
    cin >> foo; 
}

输出

The iter insert  = 2
The iter insert after = 3
The iter insert before = 1
于 2014-02-06T16:21:19.830 回答
0

是的,Mark B 提供的完全正确。我只是想提交正确的语法,以便将来可能的访问者受益。

我创建了一个 typedef:

typedef myDataContainerType::nth_index<1>::type myDataContainerType_by_id;

myDataContainerType myDataContainer;

以及根据 id 查找数据并将索引更改为插入顺序的语法:

myDataContainerType_by_id& idIndex = myContainer.get<1>();
myContainerType_by_id::iterator itId = idIndex.find(fId);

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

myDataContainerType::const_iterator itInsertionOrder = myDataContainer.project<0>(itId);

// *** Alternative way to change index which works as well
myDataContainerType::const_iterator itInsertionOrder2 = myDataContainer.iterator_to(*itId);
// ***
于 2014-02-07T08:39:08.290 回答