用于制作一组 pair<int, int> 类型元素的运算符重载
Operator overloading for making a set of elements of type pair<int, int>
如何重载一对整数的“<”(小于)运算符以将此类型的元素插入到集合中。例如,考虑以下程序
#include <stdio.h>
#include <utility>
#include <set>
using namespace std;
bool operator<(pair<int, int> a, pair<int, int> b){
if(a.second < b.second) return true;
if(a.second == b.second) return a.first < b.first;
return false;
}
int main(){
pair<int, int> a = make_pair(1, 4);
pair<int, int> b = make_pair(2, 3);
set<pair<int ,int> > s;
s.insert(b);
s.insert(a);
set<pair<int, int> >::iterator it = s.begin();
for(; it!=s.end(); it++){
printf("(%d %d)\n", it->first, it->second);
}
if(a < b) printf("a < b\n");
else printf("b < a\n");
}
以上代码产生的输出是:
(1 4)
(2 3)
b < a
我希望集合中的元素按对结构的第二个元素排序。如何做到这一点?
问题是 std::set
在内部使用 std::less
进行比较,并委托给标准库提供的 std::pair
的 operator<
。这将在 first
和 second
上按字典顺序排列你的对。
但是,您也拉入整个 namespace std
并提供您自己的 operator<
。在您执行 if(a<b)
的位置,名称查找将找到您自己提供的比较并使用它。这就是为什么你得到了矛盾的结果。
您可以编写自己的函数对象 my_less
并将其传递给 std::set
。我建议使用 std::forward_as_tuple
,但您提供的实现也可以。
#include <stdio.h>
#include <utility>
#include <set>
#include <tuple>
using namespace std;
struct my_less
{
bool operator()(pair<int, int> const& a, pair<int, int> const& b) const
{
return std::forward_as_tuple(a.second, a.first) < std::forward_as_tuple(b.second, b.first);
}
};
int main(){
pair<int, int> a = make_pair(1, 4);
pair<int, int> b = make_pair(2, 3);
set<pair<int ,int>, my_less> s;
s.insert(b);
s.insert(a);
set<pair<int, int> >::iterator it = s.begin();
for(; it!=s.end(); it++){
printf("(%d %d)\n", it->first, it->second);
}
if(my_less{}(a,b)) printf("a < b\n");
else printf("b < a\n");
}
std::set
维护其元素之间的顺序(每个值也是它自己的键,因此它必须是唯一的)。
您无法对 std::set
进行排序并颠覆此排序,但您可以定义自己的排序标准
struct sortBySecond {
bool operator()(const pair<int, int>& e1, const pair<int, int>& e2) const {
if (e1.second < e2.second)
return true;
else if (e1.second == e2.second) {
if (e1.first < e2.first)
return true;
else
return false;
}
else
return false;
}
};
int main() {
pair<int, int> a = make_pair(1, 4);
pair<int, int> b = make_pair(2, 3);
set<pair<int, int>, sortBySecond> s;
s.insert(b);
s.insert(a);
for (auto& el : s)
std::cout << "(" << el.first << ";" << el.second << ")" << std::endl;
return 0;
}
如何重载一对整数的“<”(小于)运算符以将此类型的元素插入到集合中。例如,考虑以下程序
#include <stdio.h>
#include <utility>
#include <set>
using namespace std;
bool operator<(pair<int, int> a, pair<int, int> b){
if(a.second < b.second) return true;
if(a.second == b.second) return a.first < b.first;
return false;
}
int main(){
pair<int, int> a = make_pair(1, 4);
pair<int, int> b = make_pair(2, 3);
set<pair<int ,int> > s;
s.insert(b);
s.insert(a);
set<pair<int, int> >::iterator it = s.begin();
for(; it!=s.end(); it++){
printf("(%d %d)\n", it->first, it->second);
}
if(a < b) printf("a < b\n");
else printf("b < a\n");
}
以上代码产生的输出是:
(1 4)
(2 3)
b < a
我希望集合中的元素按对结构的第二个元素排序。如何做到这一点?
问题是 std::set
在内部使用 std::less
进行比较,并委托给标准库提供的 std::pair
的 operator<
。这将在 first
和 second
上按字典顺序排列你的对。
但是,您也拉入整个 namespace std
并提供您自己的 operator<
。在您执行 if(a<b)
的位置,名称查找将找到您自己提供的比较并使用它。这就是为什么你得到了矛盾的结果。
您可以编写自己的函数对象 my_less
并将其传递给 std::set
。我建议使用 std::forward_as_tuple
,但您提供的实现也可以。
#include <stdio.h>
#include <utility>
#include <set>
#include <tuple>
using namespace std;
struct my_less
{
bool operator()(pair<int, int> const& a, pair<int, int> const& b) const
{
return std::forward_as_tuple(a.second, a.first) < std::forward_as_tuple(b.second, b.first);
}
};
int main(){
pair<int, int> a = make_pair(1, 4);
pair<int, int> b = make_pair(2, 3);
set<pair<int ,int>, my_less> s;
s.insert(b);
s.insert(a);
set<pair<int, int> >::iterator it = s.begin();
for(; it!=s.end(); it++){
printf("(%d %d)\n", it->first, it->second);
}
if(my_less{}(a,b)) printf("a < b\n");
else printf("b < a\n");
}
std::set
维护其元素之间的顺序(每个值也是它自己的键,因此它必须是唯一的)。
您无法对 std::set
进行排序并颠覆此排序,但您可以定义自己的排序标准
struct sortBySecond {
bool operator()(const pair<int, int>& e1, const pair<int, int>& e2) const {
if (e1.second < e2.second)
return true;
else if (e1.second == e2.second) {
if (e1.first < e2.first)
return true;
else
return false;
}
else
return false;
}
};
int main() {
pair<int, int> a = make_pair(1, 4);
pair<int, int> b = make_pair(2, 3);
set<pair<int, int>, sortBySecond> s;
s.insert(b);
s.insert(a);
for (auto& el : s)
std::cout << "(" << el.first << ";" << el.second << ")" << std::endl;
return 0;
}