C++ STL或Boost能否帮助按值对地图进行排序?
标题中的“排序”一词可能会误导读者。我在寻找这种行为:C++ STL或Boost能否帮助按值对地图进行排序?,c++,sorting,boost,stl,stdmap,C++,Sorting,Boost,Stl,Stdmap,标题中的“排序”一词可能会误导读者。我在寻找这种行为: { 1: 100, { 1: 1, 3: 10, => 3: 10, 5: 1000, 5: 100, 9: 1 } 9: 1000 } 也就是说,按升序将值重新指定给现有键 这不难用一个临时的: using K = int; using V = int; std::map<K, V> my
{ 1: 100, { 1: 1,
3: 10, => 3: 10,
5: 1000, 5: 100,
9: 1 } 9: 1000 }
也就是说,按升序将值重新指定给现有键
这不难用一个临时的:
using K = int;
using V = int;
std::map<K, V> myMap{ {1, 100}, {3, 10}, {5, 1000}, {9, 1} };
std::vector<V> tempVec; // insert map values into vector
std::transform(myMap.begin(), myMap.end(), std::back_inserter(tempVec),
[](auto const& mapPair) { return mapPair.second; });
std::sort(tempVec.begin(), tempVec.end());
size_t i = 0;
for (auto& mapPair : myMap) {
mapPair.second = tempVec[i++];
}
使用K=int;
使用V=int;
映射myMap{{1100},{3,10},{5,1000},{9,1};
std::vector tempVec;//将贴图值插入向量
std::transform(myMap.begin()、myMap.end()、std::back_插入器(tempVec),
[](自动常量和映射对){return mapPair.second;});
排序(tempVec.begin(),tempVec.end());
尺寸i=0;
用于(自动映射对:myMap(&M){
mapPair.second=tempVec[i++];
}
这可以简化吗?或者更好,可以就地完成吗?您不能按值对地图进行排序
struct YourType {
int key;
int value;
bool operator<(const YourType& other) const {
return std::tie(value, key) < std::tie(other.value, other.key);
}
};
由于std::map
按键组织条目以完成其工作(如O(logn)
查找和插入),因此无法更改此行为
但是,您可以使用std::set
,其中YourType
是一个元组(如std::pair
或如下所示的自定义类型),并提供自定义比较运算符,以便按值组织集合
struct YourType {
int key;
int value;
bool operator<(const YourType& other) const {
return std::tie(value, key) < std::tie(other.value, other.key);
}
};
struct YourType{
int键;
int值;
bool算子如果我们不需要有效的算法,我们可以简单地实现选择排序
for (auto mi = myMap.begin(); mi != myMap.end(); ++mi) {
auto const& mini = min_element(mi, myMap.end(), [](auto const& pa, auto const& pb) { return pa.second < pb.second; });
swap(mi->second, mini->second);
}
for(自动mi=myMap.begin();mi!=myMap.end();++mi){
auto const&mini=min_元素(mi,myMap.end(),[](auto const&pa,auto const&pb){返回pa.secondsecond,mini->second);
}
从技术上讲,如果键或值是用户定义的类型,则可以重载映射的值\u类型的std::swap(如果它们取决于使用的定义类型,则允许在std::namespace中添加重载)只交换值部分,然后使用std::sort和自定义比较器。实际上,这不是一个好主意。@Revolver\u Ocelot缺点是,在需要默认行为的上下文中,很难摆脱自定义重载,对吗?是的。但是,作为映射的value\u type
是pair
,其中默认的是behavior是编译错误,我不认为这是问题所在。人们在std::sort
上查看std::map
并试图弄清楚,这是什么魔法,这是个问题。感觉像是XY问题。如果键不必与值匹配,为什么要使用map?看起来你想要两个大小相等的排序向量,或者两个设置或其他内容。myMap[mapPair.first]=tempVec[i++]
应该是mapPair.second=tempVec[i++]
.OP实际上并不想按值对映射进行排序。他们想对映射中的值进行排序,完全打破键和值之间的关系。这根本不能回答问题。我不知道是谁对此投了赞成票。你是对的。但既然OP已经提出了一种方法,我建议在映射中使用不同的数据结构d、 @crazypeter此数据结构的行为完全不同——它对成对进行排序,而不仅仅是对值进行排序。“按升序将值重新分配给现有键”这句话让我觉得我们想保留键和值之间的关系。如果答案没有帮助,我很抱歉。