Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用std::pair键映射,其中pair元素没有顺序重要性_C++_Stl - Fatal编程技术网

C++ 使用std::pair键映射,其中pair元素没有顺序重要性

C++ 使用std::pair键映射,其中pair元素没有顺序重要性,c++,stl,C++,Stl,正如问题所说,我需要以这样的方式使用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 std::map m; int*a_p

正如问题所说,我需要以这样的方式使用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
std::map m;
int*a_ptr=新的int;
*a_ptr=15;
m[std::make_pair(1,2)]=a_ptr;

std::cout您能简单地确保这些对始终处于相同的顺序吗?使用辅助函数,如:

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);
}
std::配对我的配对(INTA,INTB)
{
如果(a
并始终使用它访问地图:

m[my_make_pair(1,2)] = a_ptr;
std::cout << m[my_make_pair(2, 1)] << std::endl;
m[my_make_pair(1,2)]=a_ptr;
std::cout
模板
结构对称对排序{
布尔运算符()(std::pair const&left,std::pair const&right)const{

如果(左。秒只需使用自定义比较器

[](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)
}
[](标准::成对常数和左侧,标准::成对常数和右侧){
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第一,rhs第二);
返回lhs_最小值
这是怎么回事? 前几行对一对中的2个元素进行了确定的排序;也就是说,您可以按任意顺序提供它们,
lhs_min
&
lhs_max
将是相同的。然后,我们对结果使用标准的等价技术。编译器将优化所有整数副本,并且
min
/
max
将为i在线


注意,为了便于键入,我使用了C++11的lambda,后来发现没有很好的方法将它们用作
std::map
的比较器,因此您必须正确地编写一个函子。

另一种解决方案是使用
std::set
而不是
std::pair
。集合按顺序存储数据,h因此,您无需订购这双鞋,因此可以精确地满足您的要求


另一方面,另一个答案是使用显式排序对的比较包装器(compare wrapper-around pair),这可能更实用。

将映射包装在一个对对对元素进行排序的类中(因此
p.first
)在将它们用作键之前?为什么要标记这个算法?@Knooth修复了这个问题。Yakk,我不敢相信我从来没有想到过它。@Tolga你也可以对指针进行异或运算,这个操作是可交换的,不会溢出。(但根据内存中对象的布局,它可能会有糟糕的哈希行为。)@millimoose这在我可以预见的其他一些情况下会派上用场。谢谢。怎么会这样?如果我有
集合a,b
并在a中插入1,2,在b中以相反的顺序插入,那么
a==b
是真的。是的,当然。它们有相同的内容。但是
std::set
是一个有序结构;也就是说,它将其内容存储在一种有序的方式。是的,当然,正因为如此,它们满足了开箱即用的要求:这两个集合比较相等,因此{1,2}的查找也将匹配键{2,1}(注意,从数学上讲,它们只是相等).I被否决为
std::set
是一个有序容器,这不是因为如果您以任意方式插入它们,它们不会比较相等(它们不会,它们比较相等)但是,
std::map
s不关心它们的键是否相等。它们关心的只是严格的弱偏序,通常由
std::less
operator@Alex:好的,谢谢你的澄清,我更新了我的答案。我把集合的数学定义和集合的STL实现搞混了e、 事实上,我忽略了一个事实,即为了实现,必须存在一个排序(尽管这与它们在这里的使用无关)。你不能这样做。
std::map
需要一个类型作为它的第三个模板参数,你给它一个lambda,这是一个值。要想在这里使用lambda作为比较器,你必须使用
auto-cmp=[]…;typedef std::map mymap;
但您仍在创建一个无人使用的全局对象。首先可以使用一个函子。此外,我认为您指定的类型必须实现函数调用运算符
()
?@snipes83不,lambda本质上是具有时髦构造函数和
运算符()的函子
。这是一个很好的解决方案。在其他一些情况下,这会很方便,但是如果它不符合顺序,它会创建另一个pair对象,而Nate Hekman的将创建一个pair对象。我还没有太多可以访问map的地方,所以现在将make_对转换为my_make_对就可以了。否则这就是答案。-1我不喜欢否决一个pair对象我也回答了一些问题,但我不喜欢这里的递归调用;编译器是否能够删除它们并不明显。不幸的是,要使用自定义PairCmp,必须创建一个新的PairCmp,但为什么不直接将其传递给
PairCmp
?4倍大小写看起来很难看。)它会更快,是的。我写了一个更快的,其中
PairCmp
预计将采用
std::pair
而不是'std::pair'。对于非平凡类型来说,这要难看得多,但可能更快:对于简单类型,我相信编译器可以在简单情况下找出递归。
[](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)
}