2014-03-27 69 views
2

现在假设我有在2D维坐标的数组,我想选择两个坐标基于两个标准:如何设置自定义的默认比较函数在STL

  • 选择最左边和最右边的坐标
  • 选择顶部和底部坐标

为了完成这个任务,我已经定义了以下功能如下:

template <typename T> 
class Coordinate //:public common::BasicCoordinate<T> 
{ 
public: 
    T x_; ///< x_coordinate 
    T y_; ///< y_coordinate 
}; 


template<typename T> 
struct compare_x_coordinate 
{ 
    bool operator() (const Coordinate<T> &i,const Coordinate<T> &j) 
    { return i.x_<j.x_; } 
} ; 

template<typename T> 
struct compare_y_coordinate 
{ 
    bool operator() (const Coordinate<T> &i,const Coordinate<T> &j) 
    { return i.y_<j.y_; } 
} ; 

然后我要做的是编写一个函数,根据compare_x_coordinatecompare_y_coordinate从坐标范围中选择两个坐标。 我可以用两个功能做到这一点:

template<typename T > 
    void find_left_right_points(const std::vector<Coordinate<T> > &ptArray, 
     Coordinate<T> &left, 
     Coordinate<T> &right) 
    { 
     compare_x_coordinate<T> mycompare; 
     std::vector<Coordinate<T> >::const_iterator it_max = std::max_element(ptArray.begin(), ptArray.end(), mycompare); 
     int index_max = it_max-ptArray.begin(); 


     std::vector<Coordinate<T> >::const_iterator it_min = std::min_element(ptArray.begin(),ptArray.end(),mycompare); 
     int index_min = it_min-ptArray.begin(); 

     left = ptArray[index_min]; 
     right = ptArray[index_max]; 
    } ; 

template<typename T > 
void find_top_bottom_points(const std::vector<Coordinate<T> > &ptArray, 
    Coordinate<T> &left, 
    Coordinate<T> &right) 
{ 
    compare_y_coordinate<T> mycompare; 
    std::vector<Coordinate<T> >::const_iterator it_max = std::max_element(ptArray.begin(), ptArray.end(), mycompare); 
    int index_max = it_max-ptArray.begin(); 


std::vector<Coordinate<T> >::const_iterator it_min = std::min_element(ptArray.begin(),ptArray.end(),mycompare); 
int index_min = it_min-ptArray.begin(); 

left = ptArray[index_min]; 
right = ptArray[index_max]; 
} ; 

当然,最好的就是这两个功能结合成一个:但是

template<typename T > 
    void find_points(const std::vector<Coordinate<T> > &ptArray, 
     Coordinate<T> &left, 
     Coordinate<T> &right, 
     // I do not know how to write the default comparasion function 
     ) 
    { 
    // compare_x_coordinate<T> mycompare; 
     std::vector<Coordinate<T> >::const_iterator it_max = std::max_element(ptArray.begin(), ptArray.end(), mycompare); 
     int index_max = it_max-ptArray.begin(); 


     std::vector<Coordinate<T> >::const_iterator it_min = std::min_element(ptArray.begin(),ptArray.end(),mycompare); 
     int index_min = it_min-ptArray.begin(); 

     left = ptArray[index_min]; 
     right = ptArray[index_max]; 
    } ; 

,我做不知道在上面的例子中如何编写默认比较函数,有什么想法?谢谢。

编辑:函数的一种可能的应用应该是:

void main(void) 
{ 
    std::vector<Coordinate> ptArray; 
    // step 1: fill the coordinates 
    ptArray.push_back(...) 
    // step 2: select the most left and right coordinates 
    Coordinate left, right; 
    find_points(ptArray,left,right); 
    // step 3: select the top and bottom coordinates 
    Coordinate top,bottom; 
    find_points(ptArray, top,left, find_top_bottom_points); 

} 
+0

你在找4个坐标? (leftmost.x,leftmost.y),(rightmost.x,rightmost.y),(topmost.x,topmost.y),(bottommost.x,bottommost.y)??或者你正在寻找2个坐标?或4个不同的值 – Ravi

+0

@Ravi,感谢您的评论。我已经举了一个例子来展示如何使用这个函数。 – feelfree

+0

从几何角度来看,你应该确定'compare_xy_coordinate'和'compare_yx_coordinate'。所以如果你有两个相同的'x'坐标,你总是得到相同的坐标,结果不取决于容器的顺序。 – pmr

回答

1

如果我理解正确的,这样做的一个方法是:

template<typename T, class Compare > 
void find_points(const std::vector<Coordinate<T> > &ptArray, 
       Coordinate<T> &left, 
       Coordinate<T> &right, 
       const Compare &cmp) { 
    find_points(ptArray, left, right, cmp); 
} 

template<typename T > 
void find_points(const std::vector<Coordinate<T> > &ptArray, 
       Coordinate<T> &left, 
       Coordinate<T> &right) { 
    find_points(ptArray, left, right, default_compare); 
} 

你也可以做使用boost ::它功能(但你可以放弃性能):

template<typename T > 
void find_points(const std::vector<Coordinate<T> > &ptArray, 
       Coordinate<T> &left, 
       Coordinate<T> &right, 
       const boost::function<bool(const Coordinate<T>&, Coordinate<T>&)> &cmp = 
        compare_x_coordinate<T>()) 
{ 
    ... 
}