Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从序列中选择最左侧和最右侧点的较短方法?_C++ - Fatal编程技术网

C++ 从序列中选择最左侧和最右侧点的较短方法?

C++ 从序列中选择最左侧和最右侧点的较短方法?,c++,C++,我试着从一组点中找到名为A、B和C、D的点,一个点有x坐标和y坐标。 A和B是最左边的点,C和D是点集中最右边的点 此外,A和B是具有相同x坐标的点,但B具有比A更大的y坐标。 C和D是具有相同x坐标的点,但D具有比C更大的y坐标 这里是for循环 // pointSeq is a vector of points // A,B,C and D are set to pointSeq[0] for(int i = 1 ; i < pointSeq.size(); i++) { if

我试着从一组点中找到名为A、B和C、D的点,一个点有x坐标和y坐标。 A和B是最左边的点,C和D是点集中最右边的点

此外,A和B是具有相同x坐标的点,但B具有比A更大的y坐标。 C和D是具有相同x坐标的点,但D具有比C更大的y坐标

这里是for循环

// pointSeq is a vector of points
// A,B,C and D are set to pointSeq[0]
for(int i = 1 ; i < pointSeq.size(); i++)
{
    if (pointSeq[i].x <= A.x)
    {
        if(pointSeq[i].x < A.x)
        {
            A = pointSeq[i]; B = pointSeq[i];
        }
        else
        {
            if(pointSeq[i].y > B.y)
            {
                B = pointSeq[i];
            }
            else if(pointSeq[i].y < A.y)
            {
                A = pointSeq[i];
            }
        }
    }
    // from here it is to find the C and D
    else if (pointSeq[i].x >= C.x)
    {
        if(pointSeq[i].x > C.x)
        {
            C = pointSeq[i], D = pointSeq[i];
        }
        else
        {
            if (pointSeq[i].y > D.y)
            {
                D = pointSeq[i];    
            }
            else if (pointSeq[i].y < C.y)
            {
                C = pointSeq[i];
            }
        }   
    }

}
这两部分是非常相似的过程,所以我想知道是否可以缩短代码使其更简单

我想让问题简单一点。它查找位于每个x-min和x-max位置的四个点。 我可以添加更多的线来查找关于y坐标的点,即y-min和y-max的四个点,在这种情况下,x坐标是不同的


多谢各位

我认为简化您在这里所做工作的一种方法是考虑定义一种将点与点进行比较的方法。给定两个点x1,y1和x2,y2,考虑这些点的字典比较,这可以通过这个函数来完成:

bool lexCompare(Point lhs, Point rhs) {
    return (lhs.x < rhs.x) || (lhs.x == rhs.x && lhs.y < rhs.y);
}
这段代码会及时运行,并且更简洁地传达您正在尝试执行的操作

或者使用std::nth_元素对元素重新排序,以将顶部的两个元素和底部的两个元素放在正确的位置:

auto comparator = [](const Point& lhs, const Point& rhs) {
                       return (lhs.x < rhs.x) || (lhs.x == rhs.x && lhs.y < rhs.y);
                  };
std::nth_element(pointSeq.begin(), pointSeq.begin() + 1, pointSeq.end(), comparator);
std::nth_element(pointSeq.begin() + 2, pointSeq.end() - 2, pointSeq.end(), comparator);

/* Sort the two-element ranges at the beginning and end. */
if (comparator(pointSeq[0], pointSet[1])) {
    std::swap(pointSeq[0], pointSeq[1]);
}
if (comparator(pointSeq[pointSeq.size() - 2], pointSeq[pointSeq.size() - 1]) {
    std::swap(pointSeq[pointSeq.size() - 2], pointSeq[pointSeq.size() - 1]);
}

Point A = pointSeq[0];
Point B = pointSeq[1];
Point C = pointSeq[pointSeq.size() - 2];
Point D = pointSeq[pointSeq.size() - 1];

为什么不使用呢?请注意,这段代码的解释非常简单,远远不能自我解释。我试着把它归结为一个更具体的目标:为什么要设置这些变量,在什么条件下设置它们?你能把这一系列的点排序并一次完成吗?这段代码已经太短了,即它缺少任何声明…要回答你提出的问题:是的,你当然可以缩短代码使它更简单。只需在一个循环中找到A和D,然后从中定义B和C。
auto comparator = [](const Point& lhs, const Point& rhs) {
                       return (lhs.x < rhs.x) || (lhs.x == rhs.x && lhs.y < rhs.y);
                  };
auto aAndD = std::minmax_element(pointSeq.begin(), pointSeq.end(), comparator);
Point A = *aAndD.first;
Point D = *aAndD.second;

/* Move A and D to the end of the sequence. */
if (aAndD.first > aAndD.second) std::swap(aAndD.first, std::aAndD.second);
std::iter_swap(aAndD.second, pointSeq.end() - 1);
std::iter_swap(aAndD.first,  pointSeq.end() - 2);

/* Get B and C. */
auto bAndC = std::minmax_element(pointSeq.begin(), pointSeq.end() - 2);
Point B = *bAndC.first;
Point C = *bAndC.second;
auto comparator = [](const Point& lhs, const Point& rhs) {
                       return (lhs.x < rhs.x) || (lhs.x == rhs.x && lhs.y < rhs.y);
                  };
std::nth_element(pointSeq.begin(), pointSeq.begin() + 1, pointSeq.end(), comparator);
std::nth_element(pointSeq.begin() + 2, pointSeq.end() - 2, pointSeq.end(), comparator);

/* Sort the two-element ranges at the beginning and end. */
if (comparator(pointSeq[0], pointSet[1])) {
    std::swap(pointSeq[0], pointSeq[1]);
}
if (comparator(pointSeq[pointSeq.size() - 2], pointSeq[pointSeq.size() - 1]) {
    std::swap(pointSeq[pointSeq.size() - 2], pointSeq[pointSeq.size() - 1]);
}

Point A = pointSeq[0];
Point B = pointSeq[1];
Point C = pointSeq[pointSeq.size() - 2];
Point D = pointSeq[pointSeq.size() - 1];