0

这是我的代码

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)视为相同?

4

3 回答 3

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一个单独的类,使用特定于它的数据成员名称,而不是通用的firstand secondstd::pair,在我看来,当您必须将它们作为单个对象传递时,它是包含不相关数据的快速解决方案。你所拥有的显然是非常相关的数据。仅仅因为std::pair碰巧能够保存正确的数据成员,并不意味着您应该使用它。

于 2013-03-16T01:41:12.733 回答
1

始终保持 X 和 Y 排序,即。在插入、搜索、删除时,首先对对进行排序,然后将排序后的对与 map 方法一起使用。

或者,制作自己的link构造函数助手来强制执行该规则,并在构造它们的任何地方直接使用它,这样您就不必进行不必要的转换。

事实上,鉴于您已经定义了一个特定类型,最好也制作类型构造函数和运算符,这样如果将来该类型发生变化,您就不必通过所有代码来更正它。

于 2013-03-16T01:38:29.410 回答
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);
}

我在这里找到了解决方案。

于 2013-03-16T01:40:52.087 回答