C++ 如何更换我的';对于';通过STL mimax算法循环查找最小/最大值

C++ 如何更换我的';对于';通过STL mimax算法循环查找最小/最大值,c++,algorithm,stl,minmax,C++,Algorithm,Stl,Minmax,我必须从a中找到最小/最大值(最小x,最小y,最大x,最大y) 向量 这是我的代码: vector<cv::Point> contour; 矢量轮廓; Min=点(640480); 最大值=点(0,0); 对于(int j=0;j Max.x)Max.x=轮廓[j].x; 如果(等高线[j].y>Max.y)Max.y=等高线[j].y; } 这个很好用。我使用mimmax STL开发了一个版本: auto XminXmax = minmax_element(contour

我必须从a中找到最小/最大值(最小x,最小y,最大x,最大y)

向量
这是我的代码:

vector<cv::Point> contour;
矢量轮廓;

Min=点(640480);
最大值=点(0,0);
对于(int j=0;j Max.x)Max.x=轮廓[j].x;
如果(等高线[j].y>Max.y)Max.y=等高线[j].y;
}
这个很好用。我使用mimmax STL开发了一个版本:

auto XminXmax = minmax_element(contour.begin(), contour.end(), [](Point p1,Point p2) {return p1.x < p2.x; });
auto YminYmax = minmax_element(contour.begin(), contour.end(), [](Point p1,Point p2) {return p1.y < p2.y; });
Point Min = Point((*XminXmax.first).x, (*YminYmax.first).y );
Point Max = Point((*XminXmax.second).x, (*YminYmax.second).y );
auto-XminXmax=minmax_元素(contour.begin(),contour.end(),[](点p1,点p2){返回p1.x
这也可以很好地工作,并给出相同的结果。 但是,由于algo minmax调用了两次,因此执行时间是两次。
是否可以通过一次调用minmax algo对其进行优化?

minmax\u元素
对象上运行比较,并将返回
对象

x
y
值是独立的,很可能
min(x)
min(y)
将属于不同的对象

对于这个特殊情况,我将使用范围

Min = Point(640, 480) ;
Max = Point(0,0) ;
for (auto &p : contour)
{
    Min.x = std::min(p.x, Min.x)
    Min.y = std::min(p.y, Min.y)
    Max.x = std::max(p.x, Max.x)
    Max.y = std::max(p.y, Max.y)
}

不,不可能通过单个调用
minmax\u元素
来优化此问题,因为
minmax\u元素
不是此问题的最佳解决方案

如果您坚持使用某些STL算法,请使用
累加

std::accumulate(begin(contour), end(contour), Bound{}, [](Bound acc, Point p)
{
    return Bound{minpos(acc.bottomleft, p), maxpos(acc.topright, p)};
});
但这需要一些准备:

#include <numeric>

struct Point
{
    int x;
    int y;

    Point(int x, int y)
        : x(x), y(y) {}
};

Point minpos(Point a, Point b)
{
    return {std::min(a.x, b.x), std::min(a.y, b.y)};
}

Point maxpos(Point a, Point b)
{
    return {std::max(a.x, b.x), std::max(a.y, b.y)};
}

struct Bound
{
    Point bottomleft;
    Point topright;

    Bound(Point bl = {640, 480}, Point tr = {0, 0})
        : bottomleft(bl), topright(tr) {}
};
#包括
结构点
{
int x;
int-y;
点(整数x,整数y)
:x(x),y(y){}
};
minpos点(a点、b点)
{
返回{std::min(a.x,b.x),std::min(a.y,b.y)};
}
点maxpos(点a、点b)
{
返回{std::max(a.x,b.x),std::max(a.y,b.y)};
}
结构绑定
{
点左下角;
右上角点;
界(点bl={640480},点tr={0,0})
:左下角(bl),右上角(tr){
};
< >代码>累加<代码>方法为循环方法的范围,我们可以考虑两个方面:

  • 可读性<代码>累积
  • 方法更好地表达了从多个点中收集单个边界框的意图。但它会导致代码稍长
  • 表演。对于这两种方法,gcc(5.3和6)生成几乎相同的代码。Clang 3.8可以对循环的范围进行矢量化,但不能对
    累加
    进行矢量化。从C++17开始,我们将标准化parallelizm TS。与
    acculate
    并行的是
    reduce
    算法,因此
    acculate/reduce
    方法将允许更大的灵活性

  • 结论:范围和
    累积/减少
    都有一些(dis)优势。但可能一种完全不同的方法是最好的:如果OP中的
    cv::Point
    意味着您使用openCV库,那么同一个库中的函数正是您试图实现的功能。

    我想STL算法在代码长度方面会更有效。因为射程更简单。但是你回答了我的问题!最后,我将使用openCV boundingRect函数。
    std::accumulate(begin(contour), end(contour), Bound{}, [](Bound acc, Point p)
    {
        return Bound{minpos(acc.bottomleft, p), maxpos(acc.topright, p)};
    });
    
    #include <numeric>
    
    struct Point
    {
        int x;
        int y;
    
        Point(int x, int y)
            : x(x), y(y) {}
    };
    
    Point minpos(Point a, Point b)
    {
        return {std::min(a.x, b.x), std::min(a.y, b.y)};
    }
    
    Point maxpos(Point a, Point b)
    {
        return {std::max(a.x, b.x), std::max(a.y, b.y)};
    }
    
    struct Bound
    {
        Point bottomleft;
        Point topright;
    
        Bound(Point bl = {640, 480}, Point tr = {0, 0})
            : bottomleft(bl), topright(tr) {}
    };