正如问题所说,我需要以这样的方式使用std :: map。
std::map<std::pair<int, int>, int*> m;
int* a_ptr = new int;
*a_ptr = 15;
m[std::make_pair(1, 2)] = a_ptr;
std::cout << *m[std::make_pair(2, 1)] << std::endl; //should output 15
现在,在我的实际实现中,所有键和值实际上都是指针。我该如何处理这个问题?
我想到了两个想法。
一个是我每次使用m[]
时都应该写一个函数
访问或写入地图,我还应m.find()
检查
其他一对组合并按此行事。
其他使用std :: unordered_map和自定义哈希
当pair
的元素位置被切换时,以某种方式没有区别。 (我不知道怎么做,如果我乘以或添加
两个指针结果不一样。如果是这样,需要一些帮助
要走的路。)
如果你能想出一个更好的方法,我会很高兴听到它,否则我已经在第二个条款中陈述了我需要帮助的内容。 (我觉得效率更高,第一个看起来不太好)
感谢。
答案 0 :(得分:6)
你能简单地确保这些对总是处于相同的顺序吗?使用辅助函数,如:
std::pair<int,int> my_make_pair(int a, int b)
{
if ( a < b ) return std::pair<int,int>(a,b);
else return std::pair<int,int>(b,a);
}
并始终使用它来访问地图:
m[my_make_pair(1,2)] = a_ptr;
std::cout << m[my_make_pair(2, 1)] << std::endl;
答案 1 :(得分:3)
template<typename T, typename PairCmp = std::less<std::pair<T,T>> >
struct symmetric_pair_sort {
bool operator()( std::pair<T,T> const& left, std::pair<T,T> const& right ) const {
if (left.second<left.first) {
return (*this)(std::make_pair( left.second, left.first ), right );
}
if (right.second<right.first) {
return (*this)(left, std::make_pair( right.second, right.first ) );
}
return PairCmp()(left, right);
}
};
// or, the far bulkier yet more efficient:
template<typename T, typename PairCmp = std::less<std::pair<T&, T&>> >
struct symmetric_pair_sort {
template<bool left_reversed, bool right_reversed>
bool Helper( std::pair<T,T> const& left, std::pair<T,T> const& right ) const {
std::pair<T&, T&> left_ordered( left_reversed?left.first:left.second, left_reversed?left.second:left.first );
std::pair<T&, T&> right_ordered( right_reversed?right.first:right.second, right_reversed?right.second:right.first );
return PairCmp()( left_ordered, right_ordered );
}
bool operator()( std::pair<T,T> const& left, std::pair<T,T> const& right ) const {
if (left.second<left.first) {
if (right.second<right.first) {
return Helper<true, true>(left, right);
} else {
return Helper<true, false>(left, right);
}
} else {
if (right.second<right.first) {
return Helper<false, true>(left, right);
} else {
return Helper<false, false>(left, right);
}
}
};
std::map<std::pair<int, int>, int*, symmetric_pair_sort<int> > m;
答案 2 :(得分:3)
只需使用自定义比较器
[](std::pair<int, int> const& lhs, std::pair<int, int> const& rhs) {
int lhs_min = std::min(lhs.first, lhs.second);
int lhs_max = std::max(lhs.first, lhs.second);
int rhs_min = std::min(rhs.first, rhs.second);
int rhs_max = std::max(rhs.first, rhs.second);
return lhs_min < rhs_min || (!(rhs_min < lhs_min) && lhs_max < rhs_max)
}
前几行确定性地排序一对中的2个元素;也就是说,您可以按任意顺序提供它们lhs_min
&amp; lhs_max
将是相同的。然后,我们使用标准等效技术来得到结果。所有整数副本都将由编译器优化,min
/ max
将被内联。
请注意,为了方便输入,我使用了C ++ 11的lambdas,并且发现没有很好的方法将它们用作std::map
的比较器,所以你必须编写一个正确的函数。
答案 3 :(得分:1)
另一种解决方案是使用std::set<int>
代替std::pair<int,int>
。设置存储他们订购的数据,因此无需订购您的数据,因此精确满足您的要求。
另一方面,使用比较包装的其他答案明确地命令对可能更实用。