2013-03-16 76 views
0

这里是我的代码处理两个标准::对(X,Y)相同的std ::对(Y,X)

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

回答

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

+0

非常感谢!它帮助,而不是返回'std :: make_pair(x,y),我返回链接(x,y)'。 – user2175966 2013-03-18 18:56:31

1

始终保持X和Y排序,即。当插入,搜索,删除时,首先让这个对进行排序,然后将这个排序对与地图方法一起使用。

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

事实上,考虑到你已经定义了一个特定的类型,建立类型构造函数和操作符也是一个很好的习惯,所以如果这种类型在将来发生变化,你不必全部通过您的代码来纠正它。

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

相关问题