【发布时间】:2020-09-22 06:24:36
【问题描述】:
我正在编写一种在集合中查找重复面孔的方法。该集合的类型是std::vector<std::tuple<int, int, int>> 所以,为了找到重复项,我尝试创建一个地图
`std::map<std::tuple<int, int, int>, int>` where key is tuple and value is the number of occurrences.
如果我添加以下数据,
std::map<std::tuple<int, int, int>, int> faceMap;
faceMap[std::make_tuple(0, 1, 2)]++;
faceMap[std::make_tuple(0, 2, 1)]++;
faceMap[std::make_tuple(1, 0, 2)]++;
faceMap[std::make_tuple(1, 2, 0)]++;
faceMap[std::make_tuple(2, 1, 0)]++;
faceMap[std::make_tuple(2, 0, 1)]++;
我希望得到 faceMap,其中只有一个键值对,键为 [0,1,2],值为 6。
为了对此进行排序,我还尝试编写如下比较器
bool containsIndex(int toCheck, int i0, int i1, int i2)
{
if (toCheck == i0 || toCheck == i1 || toCheck == i2)
return true;
else
return false;
}
struct FaceTupleComparator {
bool operator() (const std::tuple<int, int, int>& lhs,
const std::tuple<int, int, int>& rhs) const
{
auto lv0 = std::get<0>(lhs);
auto lv1 = std::get<1>(lhs);
auto lv2 = std::get<2>(lhs);
auto rv0 = std::get<0>(rhs);
auto rv1 = std::get<1>(rhs);
auto rv2 = std::get<2>(rhs);
bool i0Found = false, i1Found = false, i2Found = false;
if (containsIndex(lv0, rv0, rv1, rv2))
i0Found = true;
if (containsIndex(lv1, rv0, rv1, rv2))
i1Found = true;
if (containsIndex(lv2, rv0, rv1, rv2))
i2Found = true;
return !(i0Found && i1Found && i2Found);
}
};
并将地图制作为std::map<std::tuple<int, int, int>, int, FaceTupleComparator> faceMap;
它不适用于所有将异常作为无效比较器抛出的情况。
如果有办法在这种类型的集合中找到重复项,有人可以帮我吗?
【问题讨论】:
-
地图需要严格的弱排序,而不是相等运算符。像
operator<一样实现operator()。 -
请查看
std::map的比较器要求。您不能只是忽略要求并将其他一些功能融入其中。如果您尝试这样做,则会在内部破坏数据结构。 -
无需编写复杂的比较器,您只需对元组的元素进行排序即可。
-
使用 std::unordered_map 以获得更快的性能。如果您只是想查找重复项而不需要计数,请考虑使用 std::unordered_set。
-
如果元组表示 3d 网格的顶点或 FE(有限元)网格的元素,则排序可能是违背目的的。如果这是真的,我不确定ordered_map 或任何类型的地图是否是好的用例,因为模型有更多的优化方法
标签: c++ algorithm data-structures stl