C++ 通过索引进行快速搜索,并在C+中保持插入顺序+;
我需要一个容器,有能力搜索超过100万个项目相当快,并保持插入顺序 首先,我考虑了std::map,但它不关心插入顺序,而是根据键对数据进行排序。 我发现了一个boost::multi_索引,它将保留插入顺序,并通过索引字段(对于我的案例,它是id(不是唯一的!))快速搜索数据。所以我做了这样的事情:C++ 通过索引进行快速搜索,并在C+中保持插入顺序+;,c++,search,boost,containers,boost-multi-index,C++,Search,Boost,Containers,Boost Multi Index,我需要一个容器,有能力搜索超过100万个项目相当快,并保持插入顺序 首先,我考虑了std::map,但它不关心插入顺序,而是根据键对数据进行排序。 我发现了一个boost::multi_索引,它将保留插入顺序,并通过索引字段(对于我的案例,它是id(不是唯一的!))快速搜索数据。所以我做了这样的事情: struct myData { unsigned long id; unsigned long insertionOrder; myData (){}; myDa
struct myData
{
unsigned long id;
unsigned long insertionOrder;
myData (){};
myData (unsigned long id_,unsigned long insertionOrder_):id(id_), insertionOrder(insertionOrder _)){}
~ myData (){};
};
typedef multi_index_container<
myData,
indexed_by<
random_access<>, // keep insertion order
ordered_non_unique< member< myData, unsigned long, & myData::id> >
>
> myDataContainerType;
问题是当我在容器中搜索项目“1001”
时,迭代器+++
返回“1002”
,而迭代器-
返回“1000”
。因此,它似乎并不关心插入顺序,而是根据索引值对数据进行排序
我希望得到迭代器+++
:“1002”
和迭代器--
:“1005”
的结果。我指的是按插入顺序排列的数据
我做错了吗?如何实现像通过索引值进行快速搜索和根据插入顺序检索数据这样的功能
<强>我在Visual Studio 2008、Visual C++、Win 7 X64计算机上工作。
< P>我将使用<代码> MultMAPP < /C> >与<代码>列表< /> >配对。我将使用映射进行查找,列表将按插入顺序保存项目。在所有插入/更新/删除场景中,您需要使两个容器保持最新。如果您能详细说明您的用例,那么可能会有更好的选择 此选项将为您提供日志(n)查找,同时仍允许恒定时间删除索引和项。这与我过去实现LRU缓存的方式类似 因问题而编辑您的
boost::multi_index
尝试几乎成功了。问题是,当您使用有序索引进行查找时,迭代也是有序的。幸运的是,多索引提供了一个项目
机制来在索引之间切换。如果我正确阅读了文档:
auto ordered_iter = myMap.find(1001);
auto iter = boost::multi_index::project<0>(ordered_iter);
autoordered\u iter=myMap.find(1001);
自动iter=boost::多索引::项目(有序iter);
是的,Mark B提供的完全正确。我只是想提交正确的语法,以方便将来可能的访问者
我创建了一个typedef:
typedef myDataContainerType::nth_index<1>::type myDataContainerType_by_id;
myDataContainerType myDataContainer;
typedef myDataContainerType::n_index::type myDataContainerType_by_id;
myDataContainer类型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);
// ***
myDataContainerType_by_id&idIndex=myContainer.get();
myContainerType_by_id::迭代器itId=idIndex.find(fId);
如果(itId==idIndex.end())
返回0;
myDataContainerType::const_迭代器itInsertionOrder=myDataContainer.project(itId);
//***更改索引的替代方法也适用
myDataContainerType::const_迭代器itInsertionOrder2=myDataContainer.iterator_to(*itId);
// ***
谢谢你的回答,但是你能提供一些具体的代码示例来说明你的意思吗?如果它不能与multi_index一起使用,我会尝试一下,谢谢。我不知道那种方法。我一定会试试这个。但问题是ut是否与随机访问一起工作?或者我必须实现另一个orderd_唯一索引吗?它应该可以与multi_index
提供的任何索引类型配合使用。
auto ordered_iter = myMap.find(1001);
auto iter = boost::multi_index::project<0>(ordered_iter);
typedef myDataContainerType::nth_index<1>::type myDataContainerType_by_id;
myDataContainerType myDataContainer;
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);
// ***