如何在C++中声明一组pair的比较器?

如何在C++中声明一组pair的比较器?

C++中,pair是用于存储两个值的标准库模板类,来自<utility>头文件。但是,有时候我们需要在使用pair时按照一定的规则进行比较,这就需要声明一组比较器。下面将介绍如何在C++中声明一组pair的比较器。

pair的比较方式

在使用pair之前,我们需要了解pair的比较方式。pair的比较方式与元素的类型有关,如下所示:

  • pair.first可以进行小于比较时,pair可以进行小于比较。
  • pair.first小于另一个pair的first时,pair小于另一个pair。
  • pair.first与另一个pair的first相等且pair.second小于另一个pair的second时,pair小于另一个pair。

因此,我们可以看到,在C++中比较pair对象,优先比较pair.first,如果相等再比较pair.second

pair比较器的声明

当我们需要指定一组比较器来对pair对象进行排序或查找操作时,可以使用STL提供的std::pair_compare<T>结构体。该结构体可以被视为一个函数对象,支持status_free、function指针等过载函数,可以被传递给STL容器算法中的比较器参数。

下面是一个声明比较器的例子,针对以pair<int, string>为元素的vector进行按照第一个元素降序排列:

#include <vector>
#include <utility>
#include <algorithm>

bool compare(const std::pair<int, std::string>& p1, const std::pair<int, std::string>& p2)
{
    return p1.first > p2.first;
}

int main()
{
    std::vector<std::pair<int, std::string>> v{ {3, "hello"}, {1, "world"}, {2, "bye"} };

    std::sort(v.begin(), v.end(), compare);

    for (auto& i : v)
        std::cout << i.first << " " << i.second << std::endl;

    return 0;
}

在声明compare函数时,我们需要按照STL的Compare规范,在参数列表中声明两个输入参数:指向pair的指针或引用。函数体中,我们根据排列需求返回truefalse

上述代码中,我们将pair的第一个元素作为排序关键字,使用std::sort()对vector进行按照第一个元素降序排列,最终输出结果如下:

3 hello
2 bye
1 world

因此,我们可以看到,在进行pair排列操作时,我们只需要根据需求声明相应的比较器即可。

通过lambda表达式声明pair比较器

除了可以使用函数来声明pair比较器之外,还可以使用lambda表达式来声明。

#include <vector>
#include <utility>
#include <algorithm>

int main()
{
    std::vector<std::pair<int, std::string>> v{ {3, "hello"}, {1, "world"}, {2, "bye"} };

    std::sort(v.begin(), v.end(), [](const auto& p1, const auto& p2) {
        return p1.first > p2.first;
    });

    for (auto& i : v)
        std::cout << i.first << " " << i.second << std::endl;

    return 0;
}

在上述代码中,我们使用一个lambda表达式来声明一个比较器。在括号中,我们声明了两个输入参数p1p2,并根据要求比较它们的第一个元素。输出结果与前一个例子类似。

不同STL容器中pair的比较方法

在不同的STL容器中,pair的比较方法稍有不同。下面以setmap为例说明:

set

set中,要按照一定的规则对pair进行比较,我们可以在声明set时,指定一个比较器来进行排序。默认情况下,set会对pair进行键值比较,以pair中的第一个元素作为键值。

#include <set>
#include <utility>

int main()
{
    std::set<std::pair<int, std::string>> s;

    s.insert({ 3, "hello" });
    s.insert({ 1, "world" });
    s.insert({ 2, "bye" });

    for (auto& i : s)
        std::cout << i.first << " " << i.second << std::endl;

    return 0;
}

在上述代码中,我们声明了一个set,并将三个pair对象插入到其中。由于默认情况下set按照pair的第一个元素进行排序,因此输出结果如下:

1 world
2 bye
3 hello

如果我们需要按照pair的第二个元素进行排序,可以自定义比较器:

#include<set>
#include<utility>
#include<algorithm>

struct pair_comparer
{
    bool operator() (const std::pair<int, std::string>& p1, const std::pair<int, std::string>& p2) const
    {
        return p1.second > p2.second;
    }
};

int main()
{
    std::set<std::pair<int, std::string>, pair_comparer> s;

    s.insert({ 3, "hello" });
    s.insert({ 1, "world" });
    s.insert({ 2, "bye" });

    for (auto& i : s)
        std::cout << i.first << " " << i.second << std::endl;

    return 0;
}

在上述代码中,我们自定义了一个pair_comparer结构体,并在其中定义了一个成员函数operator(),实现按照pair的第二个元素进行排序。在声明set时,我们将这个结构体作为第二个模板参数传递进去,标记该set需要按照pair_comparer进行排序。最终输出结果如下:

2 bye
3 hello
1 world

map

set相似,我们也可以对map中的pair进行按照键值排序。默认情况下,map以pair的第一个元素作为键值,因此不需要特定的比较器。

#include <map>
#include <utility>

int main()
{
    std::map<std::pair<int, std::string>, double> m;

    m.insert({ {3, "hello"}, 1.2 });
    m.insert({ {1, "world"}, 3.4 });
    m.insert({ {2, "bye"}, 5.6 });

    for (auto& i : m)
        std::cout << i.first.first << "," << i.first.second << "," << i.second << std::endl;

    return 0;
}

在上述代码中,我们声明了一个map,并将三个pair对象作为键值对插入到其中。由于默认情况下map按照pair的第一个元素进行排序,因此输出结果如下:

1,world,3.4
2,bye,5.6
3,hello,1.2

如果我们需要按照pair的第二个元素进行排序,可以使用一个自定义的比较器:

#include <map>
#include <utility>

struct pair_comparer
{
    bool operator() (const std::pair<int, std::string>& p1, const std::pair<int, std::string>& p2) const
    {
        return p1.second > p2.second;
    }
};

int main()
{
    std::map<std::pair<int, std::string>, double, pair_comparer> m;

    m.insert({ {3, "hello"}, 1.2 });
    m.insert({ {1, "world"}, 3.4 });
    m.insert({ {2, "bye"}, 5.6 });

    for(auto& i : m)
        std::cout << i.first.first << "," << i.first.second << "," << i.second << std::endl;

    return 0;
}

在上述代码中,我们自定义了一个pair_comparer结构体,并在其中定义了一个成员函数operator(),实现按照pair的第二个元素进行排序。在声明map时,我们将这个结构体作为第三个模板参数传递进去,标记该map需要按照pair_comparer进行排序。最终输出结果如下:

2,bye,5.6
1,world,3.4
3,hello,1.2

结论

在C++中,声明一组pair的比较器是很有用的,可以用于对pair进行排序或者查找操作。我们可以使用自定义的比较器或者lambda表达式来声明,也可以在每个STL容器中使用不同的比较器进行排序。掌握了这些技巧,我们将能更加灵活地使用pair类型,并优雅地完成各种C++任务。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程