【问题标题】:Finding the left-most and right-most points of a list. std::find_if the right way to go?查找列表的最左边和最右边的点。 std::find_if 正确的方法?
【发布时间】:2010-04-16 08:31:56
【问题描述】:

我有一个 Point 对象列表(每个对象都有 x,y 属性)并且想找到最左边和最右边的点。我一直在尝试用 find_if 来做,但我不确定它要走的路,因为我似乎无法传递比较器实例。 find_if 是要走的路吗?似乎没有。那么,<algorithm> 中是否有算法可以实现这一点?

提前致谢。

#include <iostream>
#include <list>
#include <algorithm>

using namespace std;

typedef struct Point{
        float x;
        float y;
} Point;

bool left(Point& p1,Point& p2)
{
        return p1.x < p2.x;

}
int main(){
        Point p1 ={-1,0};
        Point p2 ={1,0};
        Point p3 ={5,0};
        Point p4 ={7,0};

        list <Point> points;

        points.push_back(p1);
        points.push_back(p2);
        points.push_back(p3);
        points.push_back(p4);

        //Should return an interator to p1.
        find_if(points.begin(),points.end(),left);                                                  

        return 0;
}

【问题讨论】:

    标签: c++ stl find comparator


    【解决方案1】:

    请改用std::min_element 和std::max_element。

    list<Point>::iterator left = std::min_element(points.begin(), points.end(), left);
    list<Point>::iterator right = std::max_element(points.begin(), points.end(), left);
    

    我还将left的签名更改为:

    bool left(const Point& p1, const Point& p2)
    

    【讨论】:

    • 谢谢。必须创建一个结构 left{bool operator(){...}};让它发挥作用
    • @Tom 问题似乎是名称left 与某些东西发生冲突,如果我将函数名称更改为foo 我不需要仿函数但可以直接传递函数。
    • +1 如果性能是一个问题,您可以编写自己的算法,在一次遍历列表中完成并返回一对最小值/最大值。
    【解决方案2】:

    更好的是使用 boost minmax 元素:

    http://www.boost.org/doc/libs/1_42_0/libs/algorithm/minmax/index.html

    #include <boost/algorithm/minmax_element.hpp>
    ...
    auto res = boost::minmax_element(points.begin(), points.end(), left);
    
    std::cout << "min: " << res.first << std::endl;
    std::cout << "max: " << res.second << std::endl;
    

    【讨论】:

      【解决方案3】:

      如果您使用pair&lt;float, float&gt; 而不是您自己的Point,则不需要特殊的比较器。在具有相同 x 坐标的点的 y 轴上也会有一个排序,这可能很有用。

      如果您愿意,可以通过多种方式为typedef pair&lt;float, float&gt; Point; 灌输自定义行为。例如,

      typedef pair<float, float> Point;
      
      enum AxisUnit { x, y };
      float &operator*( Point &p, AxisUnit c ) // "special case" of inner product
           { return c == x? p.first : p.second; }
      
      Point my_point( 2.5, 6.3 );
      float x_coord = my_point * x;
      

      【讨论】:

        猜你喜欢
        • 2019-11-20
        • 2018-01-13
        • 1970-01-01
        • 1970-01-01
        • 2021-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多