2013-03-16 91 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碰巧能夠保存正確的數據成員,並不意味着您應該使用它。

相關問題