Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ STL或Boost能否帮助按值对地图进行排序?_C++_Sorting_Boost_Stl_Stdmap - Fatal编程技术网

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此数据结构的行为完全不同——它对成对进行排序,而不仅仅是对值进行排序。“按升序将值重新分配给现有键”这句话让我觉得我们想保留键和值之间的关系。如果答案没有帮助,我很抱歉。