2015-12-02 81 views
2

我需要非重複的2D點的列表,所以我使用帶有自定義比較功能的std::set。插入點後我使用的函數有問題,因爲std::find有時找不到已經插入的點。std ::設置2D點的自定義比較器

const double tolerance = 0.1; 
struct MyPoint2D 
{ 
    MyPoint2D(double x, double y) : _x(x), _y(y) {} 
    double _x, _y; 
}; 
auto compMyPoint2D = [&](const MyPoint2D& pointA, const MyPoint2D& pointB) -> bool 
{ 
    if (pointA._x < pointB._x - tolerance) return true; 
    if (pointA._x > pointB._x + tolerance) return false; 
    if (pointA._y < pointB._y - tolerance) return true; 
    return false; 
}; 
std::set<MyPoint2D, decltype(compMyPoint2D)> orderedMyPoints(compMyPoint2D); 
MyPoint2D pointA(0.66,1.14); 
MyPoint2D pointB(0.75, 0.0); 
MyPoint2D pointC(0.57,1.19); 
orderedMyPoints.insert(pointA); 
orderedMyPoints.insert(pointB); 
orderedMyPoints.insert(pointC); 
if (orderedMyPoints.find(pointC)==orderedMyPoints.end()) 
{ 
    std::cout << "Not found" << std::endl; 
    orderedMyPoints.insert(pointC); 
    if (orderedMyPoints.find(pointC)==orderedMyPoints.end()) 
    std::cout << "Still not found" << std::endl; 
} 

我是否需要插入std::set之前預購的2D點或有二維點更好的比較功能?

插入所有點後,我需要使用std::find以獲取最終點索引。

我在Microsoft Visual Studio 2010上使用本機C++。

回答

5

您的比較函數是錯誤的。取出+容差。這在嘗試確定浮點值之間的絕對順序時沒有用。例如,它不強制等價的傳遞性。也就是說,如果A == B(即f(A, B)f(B, A)都是假)和B == C,那麼當您在那裏進行容差調整時,不一定是A == C

只是這樣做:

if (pointA._x < pointB._x) return true; 
if (pointA._x > pointB._x) return false; 
if (pointA._y < pointB._y) return true; 
return false; 
+0

謝謝!我的想法是使用'std :: set'來清理點的列表,並獲得兩點比容差更近的點(這就是爲什麼容差如此之大,0.1),但我發現它是不可能的用'std :: set'來做。 – JordiS

2

首先,除非你有一個理由不,它最好只是定義operator<爲類,這意味着更少的打字使用std::set等時,這就意味着你可以使用中綴<。其次,本傑明指出,不應該需要tolerance。第三,你可以簡化比較的邏輯。

你應該是這樣的:

bool operator<(const MyPoint2D& lhs, const MyPoint2D& rhs) 
{ 
    return lhs._x < rhs._x || (lhs._x == rhs._x && lhs._y < rhs._y); 
} 

然後,你可以使用std::set<MyPoint2D>

+1

如果'A'爲{0,1},'B'爲{1,0},則對於A

+0

@BenjaminLindley啊,是的,謝謝。編輯應該做的伎倆 – Daniel