2015-10-03 44 views
3

我有一個存儲應該可互換的兩個點的結構。一個結構中的多個點的運算符

struct Edge 
{ 
    unsigned short firstIndex; 
    unsigned short secondIndex; 
    Edge(unsigned short firstIndex, unsigned short secondIndex) : 
     firstIndex(firstIndex), secondIndex(secondIndex) {} 
}; 

operator==方法應該如下(爲了讓他們互換)

bool operator == (const Edge& e2) const 
{ 
    return 
     first == e2.first && second == e2.second || 
     first == e2.second && second == e2.first; 
} 

我期待,以使用該結構的std::map

創建 operator<operator>方法

我試過以下(使用乘法),但它不起作用,因爲有很多情況下不同的邊緣返回相同的VA略

bool operator < (const Edge& e2) const 
{ 
    return first * second < e2.first * e2.second; 
} 

,我想使用的代碼如下:

std::map<Edge, unsigned int> edgePoints; 
Edge e1(0, 1); 
Edge e2(1, 2); 
Edge e3(2, 0); 

edgePoints[e1] = 2; 
edgePoints[e2] = 0; 
edgePoints[e3] = 1; 

雖然因爲0 * 1 == 2 * 0所以,地圖返回2當我打電話edgePoints[e3]

代碼不與我 operator<方法工作

有誰知道operator<operator>方法,我可以使用,甚至一些其他方式映射的邊緣爲了使用std::map

+0

你可以使用'unordered_map'來代替,如果你爲你的'Edge'類型提供散列函數 – melak47

+0

這看起來像我想要的,但是我的散列函數應該是什麼? – Elipzer

+0

如果第一個<第二個整數(第二個,第一個)否則整數(第一個,第二個) –

回答

5

我會存儲以這種方式的邊緣指數,小指數總是第一指數。看起來內部表示在您的應用程序中是無關緊要的。地圖不需要operator==。下面是例子結構:

struct Edge 
{ 
    typedef unsigned short Idx; // prefer strong typedef cf boost 
    Edge(Idx a, Idx b) 
    : 
     firstIndex(std::min(a, b)), 
     secondIndex(std::max(a, b)) 
    {} 

    Idx firstIndex; 
    Idx secondIndex; 

    bool operator<(Edge const & other) 
    { 
     if (firstIndex != other.firstIndex) 
      return firstIndex < other.firstIndex; 
     return secondIndex < other.secondIndex; 
    } 
}; // Edge 

如果你想使你實現甚至更好,一些小的建議:

  • 身高:std::array<unsigned short, 2>在獨立變量firstIndexsecondIndex。這樣做可以迭代索引。
  • 如果您使用的是array,則可以使用std::lexicographical_compare縮短operator<
+1

沒有編譯器生成的'operator =='。無論如何,你不需要它用於'std :: map'。 –

+0

附註:std :: tie(firstIndex,secondIndex)

+0

@ m8mble這真的是一個更好的答案。 –

2

考慮將它們作爲排序對進行比較。

bool operator < (const Edge& e2) const 
{ 
    if (min(first, second) != min(e2.first, e2.second)) 
     return min(first, second) < min(e2.first, e2.second); 
    return max(first, second) < max(e2.first, e2.second); 
} 

編輯:當然可以拯救分鐘寫入nicelier馬克塞斯和局部變量,但這個想法應該是清楚。

編輯:其他答案的想法是更好的:迫使你的結構總是有第一個小於第二個,它會消除所有分鐘,馬克塞斯,並進行比較 - 跑得快像地獄)

+0

這似乎與我所做的測試一起工作。在我將其標記爲正確之前,讓我再做一些測試。 – Elipzer

+2

這個答案比我提供的答案慢。我認爲它不適合小測試。但是我不會將它用於大圖實例。 – m8mble

+0

@ m8mble但它保留信息,如果邊緣從A到B或B到A(可能需要) –