这是我的代码
typedef std::pair<unsigned long, unsigned long> link;
std::map<link, double> container;
我要做的是计算从X到Y的距离,并将其作为container.insert存储在容器中(std :: make_pair(link,distance)); 并说现在我必须计算从Y到X的距离,而不是重做整个计算,从容器中获取存储的值,即..,链接和距离。
我目前的实施仅适用于(X,Y)
std::map<link, double>::iterator It = container.begin();
std::pair<unsigned long, unsigned long> k = link(X,Y);
It = container.find(K);
if(It != container.end()) { distance = It->second; }
else { /* distance = /* complex calc */ container.insert(std::make_pair(k,distance)); }
如何使其一般化,以便将链接(X,Y)和链接(Y,X)视为相同?
答案 0 :(得分:3)
为地图使用不同的键比较器,如下所示:
bool link_compare(link lhs, link rhs) // note: parameters taken by value
{
if (lhs.first > lhs.second) std::swap(lhs.first,lhs.second);
if (rhs.first > rhs.second) std::swap(rhs.first,rhs.second);
return lhs < rhs;
}
std::map<link, double, bool(*)(link,link)> container(link_compare);
我认为,您应该考虑将link
作为单独的类,使用特定于其的数据成员名称,而不是通用的first
和second
。在我看来,std::pair
是一个快速修复,用于在必须将它们作为单个对象传递时包含不相关的数据。你所拥有的显然是非常相关的数据。仅仅因为std::pair
碰巧能够容纳正确的数据成员,并不意味着你应该使用它。
答案 1 :(得分:1)
始终保持X和Y排序,即。插入,搜索,删除时,首先对该对进行排序,然后将该排序对与地图方法一起使用。
或者,创建自己的link
构造函数帮助程序来强制执行该规则,并在构造它们的任何位置直接使用它,这样就不必进行必要的转换。
事实上,鉴于您已经定义了一个特定的类型,最好还是创建类型构造函数和运算符,这样如果将来该类型发生更改,您就不必完成所有类型代码来纠正它。
答案 2 :(得分:1)
制作自己的make_pair函数。通过这种方式,您可以始终保持订购。
typedef std::pair<unsigned long, unsigned long> link;
link make_my_pair(unsigned long x, unsigned long y) {
if (x < y ) return std::make_pair(x, y);
return std::make_pair(y, x);
}
我找到了解决方案here。