使用 lambda 对 std::map 进行排序

Posted

技术标签:

【中文标题】使用 lambda 对 std::map 进行排序【英文标题】:Sorting a std::map using lambda 【发布时间】:2019-11-10 14:01:29 【问题描述】:

我有一个由键(类型字符串)和数据(类型元组)组成的映射。 我尝试使用 lambda 对我的地图进行排序(请参见下面的代码),但是当我编译时出现错误提示

严重性代码描述项目文件行抑制状态 错误 C2676 二进制“-”:“const std::_Tree_unchecked_iterator>>>”未定义此运算符或转换为预定义运算符可接受的类型 和 [ _Kty=std::字符串, _Ty=std::tuple ] SandBox C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\include\algorithm 3466

严重性代码描述项目文件行抑制状态 错误 C2672 '_Sort_unchecked': 找不到匹配的重载函数 SandBox C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\include\algorithm 3466

我的代码:

#include <iostream>
#include <string>
#include <tuple>
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;


int main() 
    std::vector<std::string> strarr  "zone", "abigail", "theta", "form", "libe", "zas", "theta", "abigail";

    int length = strarr.size();

    std::string str = "";

    map<string, tuple<int, int>> myMap;

    for (int i = 0; i < length; i++)
        myMap[strarr[i]] = make_tuple(strarr[i].length(), ++(get<1>(myMap[strarr[i]])));


    typedef std::function<bool(std::pair<string, tuple< int, int >>, std::pair<string, tuple< int, int >>)> Comparator;

    Comparator compFunctor =
        [](std::pair<string,tuple< int, int>> el1, std::pair<string, tuple< int, int >> el2)
    
        return (get<0>(el1.second) < get<0>(el2.second));
    ;

    std::sort(myMap.begin(), myMap.end(), compFunctor);

那么错误是什么?我确信这很愚蠢,但我自己无法弄清楚。

提前谢谢你。

【问题讨论】:

std::map 自动按键排序,因此您不能按值对该映射进行排序。您需要的是第二张翻转的地图。然后你有两个地图,可以包含在一个“多地图”中,如***.com/a/5056797/5652483所示 多图的另一个名称是“BiMap”。请参阅gist.github.com/ScottHutchinson/… 的实现 【参考方案1】:

您的错误是 std::sort 需要 random access iterator 但 std::map 的迭代器是 bidirectional iterator。您将看到 operator-() 没有为 bidrectional iterators 定义

查看类型要求here。

除此之外,您正在做的事情似乎很奇怪。看起来您正在尝试根据其值的第一个元素对地图进行排序。使用(默认情况下)std::less 在键类型上对映射进行隐式排序。如果您想以不同的顺序进行排序,您应该在地图上使用自定义比较器。

【讨论】:

【参考方案2】:

std::map 是 red-black 树。您不能按值对其进行排序。如果您希望您的地图按值排序,则需要翻转它。

struct compFunctor
bool operator()(tuple< int, int> el1, tuple< int, int > el2) const 
     return get<0>(el1) < get<0>(el2);

;

map< tuple<int, int>, string, compFunctor> myMap:

【讨论】:

这行不通。 compFunctor 可用于比较 pair&lt;string,tuple&lt; int, int&gt;&gt;,但 myMap 需要可以比较 pair&lt;tuple&lt; int, int&gt;, string&gt; 的东西。

以上是关于使用 lambda 对 std::map 进行排序的主要内容,如果未能解决你的问题,请参考以下文章

尝试对 std::map<int, class> 进行排序时出错

C++ std::map sort 如何按值排序 自定义比较函数 比较对象某个字段

使用 std::string 作为字典顺序的键对 unordered_map 进行排序

使用 lambda 函数在 std::unordered_map 中查找最小值

为什么内置排序无法对向量的映射进行排序?

对对象图进行排序 C++