【问题标题】:How order coordinate pairs?如何排序坐标对?
【发布时间】:2019-02-26 22:07:18
【问题描述】:

有人知道我如何在 C++ 中订购一对坐标 (x,y) 吗?

比如先是第一象限的坐标,然后是第二象限的坐标,以此类推

我已经用排序方法尝试过算法库,但它不起作用。

bool com(Coordenada a, Coordenada b){
    return a.getX() < b.getX() || a.getY() < b.getY();
}

void mapa::sortVertices(){
    std::sort (ver.begin(), ver.end(), com);
}

例如,之前:

x=-1;y=-1
x=1;y=1
x=1;y=-1
x=-1;y=1

之后:

x=1;y=1
x=1;y=-1
x=-1;y=-1
x=-1;y=1

【问题讨论】:

  • 请分享您尝试过的代码
  • 你试过用sort做什么?您是否提供了某种形式的自定义比较方式?
  • 如果 a 的任一坐标小于 b,您的比较将返回 True。这就是你想要的吗?
  • @kelalaka 我想是西班牙语或类似的语言。

标签: c++ algorithm sorting math


【解决方案1】:

您确定您的预期结果是正确的吗?因为它们没有按顺序排列在象限 I、II、III、IV 中

x=1;y=1   → I
x=1;y=-1  → IV
x=-1;y=-1 → III
x=-1;y=1  → II

根据quadrant definition,结果应该是

x=1;y=1   → I
x=-1;y=1  → II
x=-1;y=-1 → III
x=1;y=-1  → IV

排序有多种解决方案:

这是来自Akshat的解决方案

bool operator<(Point p1, Point p2) 
{
    if (p1.getY() == 0 && p1.getX() > 0) 
        return true;  // angle of p1 is 0, thus p2 > p1

    if (p2.getY() == 0 && p2.getX() > 0) 
        return false; // angle of p2 is 0 , thus p1 > p2

    if (p1.getY() > 0 && p2.getY() < 0) 
        return true; // p1 is between 0 and 180, p2 between 180 and 360

    if (p1.getY() < 0 && p2.getY() > 0) 
         return false;
    // return true if p1 is clockwise from p2
    return p1.getX() * p2.getY() - p1.getY() * p2.getX() > 0;
}

如果 Peter Ruderman 的建议是您想要的,那么您可以使用 std::tie 进行比较功能

std::sort (ver.begin(), ver.end(), std::tie(a.getX(), a.getY()) < std::tie(b.getX(), b.getY()));

【讨论】:

    【解决方案2】:

    您有 2 个选项。您可以为您的结构 Coordenada 重载 ,或者您可以定义一个自定义比较函数并将它作为排序参数传递。我做了后者。

    在这里你可以看到它的代码。

    #include <vector>
    #include <algorithm>
    #include <iostream>
    
    struct Coordenada {
        int x, y;
    };
    
    int findQuad(const Coordenada& a) {
        if(a.x >= 0 && a.y >= 0) return 1;
        if(a.x < 0 && a.y >= 0) return 2;
        if(a.x < 0 && a.y < 0) return 3;
        return 4;
    }
    
    bool cmp(const Coordenada& a, const Coordenada& b) {
        return findQuad(a) < findQuad(b);
    }
    
    int main() {
    
        std::vector<Coordenada> vetor(10);
    
        for(int i = 0; i < 10; ++i) {
            vetor[i].x = rand() - rand();
            vetor[i].y = rand() - rand();
        }
    
        std::sort(vetor.begin(), vetor.end(), cmp);
    
        for(int i = 0; i < 10; ++i) {
            std::cout << vetor[i].x << " " << vetor[i].y << " quad = " << findQuad(vetor[i]) << std::endl;
        }
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      问题是你没有用你的谓词定义一个有效的排序。如果你想定义坐标的总顺序,你可以使用这样的东西:

      bool CoordinateLess(Coordenada a, Coordenada b)
      {
        return a.getX() < b.getX() || (a.getX() == b.getX() && a.getY() < b.getY());
      }
      

      【讨论】:

      • OP 的排序有效。它将沿对角线从左下角到右上角对点进行排序。
      • @stark 不是,因为它不是不对称的:(5,2)&lt;(2,5)(2,5)&lt;(5,2) 都是真的。
      • 不幸的是,第四象限中的 (1; -1) 将排在第二象限中的 (-1; -1) 之前
      猜你喜欢
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 2018-05-15
      • 2021-08-30
      相关资源
      最近更新 更多