找到极端点,哪个循环更好?

时间:2017-03-17 15:31:33

标签: c++

假设我们有一组带(x,y)坐标的点。我试图找到minXminYmaxXmaxY而不进行排序。

所以,我想知道的是这两种方式之间是否有任何速度差异。

方法1

minX = minY = maxX = maxY = points[0];
for(int i = 1 ; i < points.size(); i++)
{
    if(minX > points[i].x)
    {
        minX = points[i].x;
    }
    if(minY > points[i].y)
    {
        minY = points[i].y;
    }
    if(maxX < points[i].x)
    {
        maxX = points[i].x;
    }
    if(maxY < points[i].y)
    {
        maxY = points[i].y;
    }
}

方法2

minX = minY = maxX = maxY = points[0];
for(int i = 1 ; i < points.size(); i++)
{
    if(minX > points[i].x)
    {
        minX = points[i].x;
    }
}
for(int i = 1 ; i < points.size(); i++)
{
    if(minY > points[i].y)
    {
        minY = points[i].y;
    }
}
for(int i = 1 ; i < points.size(); i++)
{
    if(maxX < points[i].x)
    {
        maxX = points[i].x;
    }
}
for(int i = 1 ; i < points.size(); i++)
{
    if(maxY < points[i].y)
    {
        maxY = points[i].y;
    }
}

2 个答案:

答案 0 :(得分:3)

由于i在第一种情况下从1开始,接受它们相当等效 - 第二种情况的行为看起来像 undefined 对我来说你似乎正在阅读未经初始化的数据 - 第一种情况是丰满的。它更容易阅读,可能更快,因为它会执行更少的语句,假设没有编译器优化

第一种情况也更容易维护。在修复第二种情况的未定义行为时,您需要更改4个循环。

虽然考虑使用std::minmax_element来提高可读性并完全依赖显式循环。

答案 1 :(得分:2)

撇开芭丝谢芭关于使用minmax_element的建议,我想提供一个在这种情况下使用它的例子。

const auto xMinMaxPair = std::minmax_element(std::begin(points), std::end(points), [](auto const& a, auto const& b)
{
    return (a.x < b.x);
});

const auto yMinMaxPair = std::minmax_element(std::begin(points), std::end(points), [](auto const& a, auto const& b)
{
    return (a.y < b.y);
});

由您决定是否更适合您的使用。但是有更多的选择可供选择总是很好。

下面是一个使用它的例子(你可以see it running here)。

#include <iostream>
#include <algorithm>
#include <vector>

struct Point
{
    Point(float const px = 0.0f, float const py = 0.0f)
        : x{ px }, y{ py }
    {

    }

    float x;
    float y;
};

void FindMinMaxPoint(std::vector<Point> const& points, Point& xMinMax, Point& yMinMax)
{
    const auto xMinMaxPair = std::minmax_element(std::begin(points), std::end(points), [](auto const& a, auto const& b)
    {
        return (a.x < b.x);
    });

    const auto yMinMaxPair = std::minmax_element(std::begin(points), std::end(points), [](auto const& a, auto const& b)
    {
        return (a.y < b.y);
    });

    xMinMax.x = xMinMaxPair.first->x;
    xMinMax.y = xMinMaxPair.second->x;

    yMinMax.x = yMinMaxPair.first->y;
    yMinMax.y = yMinMaxPair.second->y;
}

int main()
{
    auto points = std::vector<Point>{};

    points.push_back({ 1.0f, 1.0f });
    points.push_back({ 3.0f, 2.0f });
    points.push_back({ 8.0f, 0.0f });
    points.push_back({ 5.0f, 7.0f });

    auto xMinMax = Point{ };
    auto yMinMax = Point{ };

    FindMinMaxPoint(points, xMinMax, yMinMax);

    std::cout << "Min X: " << xMinMax.x << std::endl;
    std::cout << "Max X: " << xMinMax.y << std::endl;

    std::cout << "Min Y: " << yMinMax.x << std::endl;
    std::cout << "Max Y: " << yMinMax.y << std::endl;

    return 0;
}