Algorithm 将stl映射转换为基于数值的键排序列表的好算法,algorithm,sorting,stl,map,c++03,Algorithm,Sorting,Stl,Map,C++03,我有一张stl地图,类型如下:
map<Object*, baseObject*>
如果我想返回一个对象列表(std::list),按baseObject.ID的顺序对其排序的最佳方法是什么
我是不是一直在寻找每一个数字或是什么?我不希望将映射更改为boost映射,尽管我不一定反对在返回函数中执行一些自包含的操作,如
GetObjectList(std::list<Object*> &objects)
{
//sort the map into the l
),按baseObject.ID的顺序对其排序的最佳方法是什么
我是不是一直在寻找每一个数字或是什么?我不希望将映射更改为boost映射,尽管我不一定反对在返回函数中执行一些自包含的操作,如
GetObjectList(std::list<Object*> &objects)
{
//sort the map into the list
}
GetObjectList(标准::列表和对象)
{
//将地图排序到列表中
}
编辑:也许我应该遍历obj->baseobj并将其复制到baseobj.ID->obj的映射中?我将创建一个新映射,该映射具有使用对象的组件ID的排序标准。从第一个映射填充第二个映射(只需遍历或std::copy in)。然后可以使用迭代器按顺序读取此映射
与使用向量或列表(log(n)time而不是常量time)相比,这在插入方面有一点开销,但它避免了在创建向量或列表后进行排序,这很好
此外,您可以在以后的程序中向它添加更多元素,它将保持其顺序,而无需度假村。我将创建一个新的地图,该地图具有使用对象组件id的排序标准。从第一个映射填充第二个映射(只需遍历或std::copy in)。然后可以使用迭代器按顺序读取此映射
与使用向量或列表(log(n)time而不是常量time)相比,这在插入方面有一点开销,但它避免了在创建向量或列表后进行排序,这很好
此外,您可以在以后的计划中为其添加更多元素,并且它可以在不需要度假村的情况下维持其秩序。我认为您可以使用:
GetObjectList(std::list<Object*> &objects)
{
std::vector <Object*> vec;
vec.reserve(map.size());
for(auto it = map.begin(), it_end = map.end(); it != it_end; ++it)
vec.push_back(it->second);
std::sort(vec.begin(), vec.end(), [](Object* a, Object* b) { return a->ID < b->ID; });
objects.assign(vec.begin(), vec.end());
}
GetObjectList(标准::列表和对象)
{
std::vec;
向量保留(map.size());
for(auto it=map.begin(),it_end=map.end();it!=it_end;++it)
向量推回(它->秒);
排序(vec.begin(),vec.end(),[](Object*a,Object*b){返回a->IDID;});
赋值(vec.begin(),vec.end());
}
我认为您可以使用:
GetObjectList(std::list<Object*> &objects)
{
std::vector <Object*> vec;
vec.reserve(map.size());
for(auto it = map.begin(), it_end = map.end(); it != it_end; ++it)
vec.push_back(it->second);
std::sort(vec.begin(), vec.end(), [](Object* a, Object* b) { return a->ID < b->ID; });
objects.assign(vec.begin(), vec.end());
}
GetObjectList(标准::列表和对象)
{
std::vec;
向量保留(map.size());
for(auto it=map.begin(),it_end=map.end();it!=it_end;++it)
向量推回(它->秒);
排序(vec.begin(),vec.end(),[](Object*a,Object*b){返回a->IDID;});
赋值(vec.begin(),vec.end());
}
我要做的是首先将键(因为您只想返回这些键)提取到向量中,然后对其排序:
std::vector<baseObject*> out;
std::transform(myMap.begin(), myMap.end(), std::back_inserter(out), [](std::pair<Object*, baseObject*> p) { return p.first; });
std::sort(out.begin(), out.end(), [&myMap](baseObject* lhs, baseObject* rhs) { return myMap[lhs].componentID < myMap[rhs].componentID; });
std::向量输出;
std::transform(myMap.begin(),myMap.end(),std::back_插入器(out),[](std::pair p){return p.first;});
std::sort(out.begin(),out.end(),[&myMap](baseObject*lhs,baseObject*rhs){返回myMap[lhs].componentID
如果编译器不支持lambda,只需将它们重写为自由函数或函数对象即可。我只是用lambdas来简洁
对于性能,我可能会在向量中保留足够的空间,而不是让它逐渐扩展
(还要注意,我还没有测试代码,因此可能需要稍微修改一下)
另外,我不知道这个映射应该表示什么,但是持有一个键类型和值类型都是指针的映射确实会让我感到“糟糕的C++”刺痛。它散发着手动内存管理和混乱(或不存在)的所有权语义的味道
您提到在列表中获取输出,但是向量几乎肯定是一个性能更好的选项,所以我使用了它。列表
更可取的唯一情况是,实际上您不打算对其进行迭代,并且如果您需要确保指针和迭代器在修改列表后保持有效。我要做的是首先将键(因为您只想返回键)提取到向量中,然后对其进行排序:
std::vector<baseObject*> out;
std::transform(myMap.begin(), myMap.end(), std::back_inserter(out), [](std::pair<Object*, baseObject*> p) { return p.first; });
std::sort(out.begin(), out.end(), [&myMap](baseObject* lhs, baseObject* rhs) { return myMap[lhs].componentID < myMap[rhs].componentID; });
std::向量输出;
std::transform(myMap.begin(),myMap.end(),std::back_插入器(out),[](std::pair p){return p.first;});
std::sort(out.begin(),out.end(),[&myMap](baseObject*lhs,baseObject*rhs){返回myMap[lhs].componentID
如果编译器不支持lambda,只需将它们重写为自由函数或函数对象即可。我只是用lambdas来简洁
对于性能,我可能会在向量中保留足够的空间,而不是让它逐渐扩展
(还要注意,我还没有测试代码,因此可能需要稍微修改一下)
另外,我不知道这个映射应该表示什么,但是持有一个键类型和值类型都是指针的映射确实会让我感到“糟糕的C++”刺痛。它散发着手动内存管理和混乱(或不存在)的所有权语义的味道
您提到在列表中获取输出,但是向量几乎肯定是一个性能更好的选项,所以我使用了它。列表
唯一可取的情况是,实际上您不打算对其进行迭代,并且如果您需要保证指针和迭代器在修改列表后保持有效。首先,我不会使用std::list
,而是使用std::vector
。现在,对于特定的问题,您需要执行两个操作:生成容器,根据您的条件对其进行排序
// Extract the data:
std::vector<Object*> v;
v.reserve( m.size() );
std::transform( m.begin(), m.end(),
std::back_inserter(v),
[]( const map<Object*, baseObject*>::value_type& v ) {
return v.first;
} );
// Order according to the values in the map
std::sort( v.begin(), v.end(),
[&m]( Object* lhs, Object* rhs ) {
return m[lhs]->id < m[rhs]->id;
} );
同样,这可能比原始版本快或慢。。。简介。首先,我不会使用std::list
,而是使用std::vector
。现在,对于特定的问题,您需要执行两个操作:生成容器,根据您的条件对其进行排序
// Extract the data:
std::vector<Object*> v;
v.reserve( m.size() );
std::transform( m.begin(), m.end(),
std::back_inserter(v),
[]( const map<Object*, baseObject*>::value_type& v ) {
return v.first;
} );
// Order according to the values in the map
std::sort( v.begin(), v.end(),
[&m]( Object* lhs, Object* rhs ) {
return m[lhs]->id < m[rhs]->id;
} );
同样,这可能比原始数据更快或更慢