set::find 查找不存在的元素

set::find finds an element that does not exist

本文关键字:元素 不存在 查找 find set      更新时间:2023-10-16

我有以下Edge类:

class Edge {
public:
int src, dest;
bool operator== (const Edge &edge) const {
return ((src == edge.src) && (dest == edge.dest)) || ((src == edge.dest) && (dest == edge.src));
}
bool operator<(const Edge& edge) const {
return !(((src == edge.src) && (dest == edge.dest)) || ((src == edge.dest) && (dest == edge.src)));
}
Edge(int src, int dest) {
this->src = src;
this->dest = dest;
}
};

覆盖<运算符的要点是当我尝试在应等于Edge(1, 0)的集合中findEdge(0, 1)。但是,以下测试代码无法执行此操作,std::find返回甚至不存在的边缘:

Edge edge(0, 3);
set<Edge> test;
test.insert(Edge(3, 1));
test.insert(Edge(3, 0));
auto a = test.find(edge);
cout << a->src << " " << a->dest << endl;

这将奇怪地打印出2 0.我不知道为什么,我是新手C++任何帮助都是值得赞赏的。

您当前没有有效的Compareforstd::set,因此您的程序具有未定义的行为。

这是一个与您的==兼容的

bool operator<(const Edge& edge) const {
return std::minmax(src, dest) < std::minmax(edge.src, edge.dest);
}

这也可用于简化您的==

bool operator==(const Edge& edge) const {
return std::minmax(src, dest) == std::minmax(edge.src, edge.dest);
}

代码中有两个问题。

首先,不要检查test.find()是否返回有效的边;请注意,如果未找到元素,find返回end()

其次,您的<运算符没有实现严格的排序,它实际上只是定义了一个!=。为了克服这个问题,我会规范化每个边,以便始终将下部节点视为起点;然后根据起始节点做出决定,并且仅当它们相等时,才考虑目标节点:

class Edge {
public:
int src, dest;
bool operator== (const Edge &edge) const {
return ((src == edge.src) && (dest == edge.dest)) || ((src == edge.dest) && (dest == edge.src));
}
bool operator<(const Edge& edge) const {
//    return !(((src == edge.src) && (dest == edge.dest)) || ((src == edge.dest) && (dest == edge.src)));
int thisSrc = std::min(src,dest);
int thisDest = std::max(src,dest);
int eSrc = std::min(edge.src,edge.dest);
int eDest = std::max(edge.src,edge.dest);
if (thisSrc < eSrc) {
return true;
} else if (thisSrc > eSrc) {
return false;
} else {
return thisDest < eDest;
}
}
Edge(int src, int dest) {
this->src = src;
this->dest = dest;
}
};
#include <set>
int main() {
Edge edge(0, 3);
std::set<Edge> test;
test.insert(Edge(3, 1));
test.insert(Edge(3, 0));
auto a = test.find(edge);
if (a == test.end()) {
std::cout << "edge not found." << std::endl;
} else {
std::cout << a->src << " " << a->dest << std::endl;
}
}

输出:

3 0