2016-02-29 212 views
2

我有一個問題,雖然我明白,這是一個愚蠢的問題要問,但我沒有找到我自己的解決方案。Std :: map std :: set包含重複鍵

所以,我試圖積累一個具有獨特結構的值的容器。

struct Symbol { 
    D2D1_RECT_F bbox; 
    wchar_t data; 
    fz_font_s* font; 
    float color[4]; 
}; 

我在做什麼是試圖用std::mapstd::set。意識到,我需要提供一個謂詞,以便爲容器提供一種確定順序的方法。我所擁有的是:

struct SymbolCmp { 
    bool operator() (const Symbol& lhs, const Symbol& rhs) const 
    { 
     auto errorHandler = (lhs.bbox.top == rhs.bbox.top) ? (lhs.bbox.left < rhs.bbox.left) : lhs.bbox.top < rhs.bbox.top; 

     if (lhs.data == rhs.data && 
      lhs.font != rhs.font) { 
      return errorHandler; 
     } 

     float lArea = (lhs.bbox.bottom - lhs.bbox.top) * 
      (lhs.bbox.right - lhs.bbox.left); 
     float rArea = (rhs.bbox.bottom - rhs.bbox.top) * 
      (rhs.bbox.right - rhs.bbox.left); 

     auto relative = (lArea/rArea < 0.95f || 
      lArea/rArea > 1.05f); 

     return (lhs.data == rhs.data) ? relative && errorHandler : (lhs.data < rhs.data); 
    } 
}; 

然後,我只是嘗試的std::set<Symbol, SymbolCmp>std::map<Symbol, byte, SymbolCmp>內插入值。

令人遺憾的是,結果令人沮喪,因爲我得到的東西離對象很遠,只包含唯一鍵。 Symbol的大部分都有重複。

所以我真的明白,我錯過了什麼?

+0

你是否用兩個符號a和b檢查了SymbolCmp(a,b)和SymbolCmp(b,a)的返回值? – Anedar

+0

沒有仔細看,但在我看來'SymbolCmp'不滿足[嚴格 - 弱排序](https://www.sgi.com/tech/stl/StrictWeakOrdering.html)。提示:如果'relative'總是'true',它還會發生嗎? –

+0

需要嚴格的弱排序。你能保證用你寫的所有代碼嗎?只是使用浮點本身來確定順序是可疑的。 – PaulMcKenzie

回答

1

您的謂詞不能確保嚴格無序的排序。下面應該工作:

struct SymbolCmp { 
    bool operator() (const Symbol& lhs, const Symbol& rhs) const 
    { 
     if(lhs.data == rhs.data) { 
      return (lhs.bbox.top == rhs.bbox.top) ? (lhs.bbox.left < rhs.bbox.left) : lhs.bbox.top < rhs.bbox.top; 
     } else { 
      return lhs.data < rhs.data; 
     } 
    } 
}; 

如果你想使用fontcolor和尺寸的邏輯,確保按照strct弱順序約束。

+0

你能解釋一下,在我的謂詞中嚴格無序的排序有什麼問題?我的意思是,在什麼情況下它將無法提供訂單? –

+0

@AleksandrKurinnoi如果有三個類A,B和C,使得A.font = B.font,並且這些區域幾乎相同,那麼對於A