c++ 如何在双精度向量的向量上定义小于的比较运算符

ff29svar  于 2022-11-27  发布在  其他
关注(0)|答案(2)|浏览(161)

我的问题基本上与[1]相同,但挑战在于比较嵌套的vector<vector<double>>
作为我面临的问题的背景:我有一个基于std::set的n路索引,其中的项主要按时间排序,其次按几何排序。也就是说,相等的多边形应该有相同的索引,但它们的实际顺序实际上并不重要。重要的是,在这种情况下,less-comparator必须是稳定的,也就是说,当一个项既不小于也不大于时,它必须被视为相等。
因此,vector<vector<double>>表示具有可选洞的多边形(第一个向量是外环,任何后续向量都是洞)。
[1][how to define a comparison operator (less than) on array of doubles?](https://stackoverflow.com/questions/53637613/how-to-define-a-comparison-operator-less-than-on-array-of-doubles)
编辑:这个问题不是问如何实现小于运算符,而是如标题所示,关于如何通过使用小于比较来比较给定的双精度向量与另一个向量...这是一个更具挑战性的问题...
这个问题可以用不同的方法来解决,但是我特别寻找一个解决方案,它允许使用对象(几何体)作为具有多个绑定索引属性的集合的一部分。

qkf9rpyu

qkf9rpyu1#

你真的需要更多的类型

struct Point
{
    double x;
    double y;
    double z; // ???
};

struct BasicPolygon
{
    std::vector<Point> shape;
};

struct Polygon
{
    BasicPolygon shell;
    std::vector<BasicPolygon> holes;
};

=default开始,对这些类型使用operator<=>,并检查我们希望相等的情况是否被视为相等。
在这一点上,如果每个点都以相同的顺序匹配,那么一个多边形就等于另一个多边形。如果你要求只在起始点不同的多边形被视为相等,事情会变得更困难。如果是这样的话,我建议你规范所有多边形从最低点开始。

void BasicPolygon::canonicalize()
{
    auto it = std::min_element(shape.begin(), shape.end());
    std::rotate(shape.begin(), it, shape.end());
}

void Polygon::canonicalize()
{
    shell.canonicalize();
    std::for_each(holes.begin(), holes.end(), std::mem_fn(&BasicPolygon::canonicalize));
}

如果你不能改变几何体,你可以在每次比较时找到规范的起点,然后做一个std::lexicographic_compare s. N. b的序列。由于大小检查,这是一个不同于首先规范化的总顺序。

bool operator<(const BasicPolygon & lhs, const BasicPolygon & rhs)
{
    if (lhs.size() < rhs.size()) return true;
    if (rhs.size() < lhs.size()) return false;

    auto l_first = std::min_element(lhs.shape.begin(), lhs.shape.end());
    auto r_first = std::min_element(rhs.shape.begin(), rhs.shape.end());
    const auto l_last = l_first;
    const auto r_last = r_first;

    auto l_rem = std::distance(l_first, lhs.shape.end());
    auto r_rem = std::distance(r_first, rhs.shape.end());

    if (l_rem < r_rem)
    {
        if (std::lexicographic_compare(l_first, lhs.shape.end(), r_first, r_first + l_rem)) return true;
        if (std::lexicographic_compare(r_first, r_first + l_rem, l_first, lhs.shape.end()) return false;

        r_first += l_rem;
        r_rem -= l_rem;
        l_first = lhs.shape.begin();

        if (std::lexicographic_compare(l_first, l_first + r_rem, r_first, rhs.shape.end()) return true;
        if (std::lexicographic_compare(r_first, rhs.shape.end(), l_first, l_first + r_rem)) return false;

        l_first += r_rem;
        r_first = rhs.shape.begin();

        if (std::lexicographic_compare(l_first, l_last, r_first, r_last)) return true;
        if (std::lexicographic_compare(r_first, r_last, l_first, l_last) return false;
    } else {
        if (std::lexicographic_compare(l_first, l_first + r_rem, r_first, rhs.shape.end()) return true;
        if (std::lexicographic_compare(r_first, rhs.shape.end(), l_first, l_first + r_rem)) return false;

        l_first += r_rem;
        l_rem -= r_rem;
        r_first = rhs.shape.begin();

        if (std::lexicographic_compare(l_first, lhs.shape.end(), r_first, r_first + l_rem)) return true;
        if (std::lexicographic_compare(r_first, r_first + l_rem, l_first, lhs.shape.end()) return false;

        r_first += l_rem;
        l_first = lhs.shape.begin();

        if (std::lexicographic_compare(l_first, l_last, r_first, r_last)) return true;
        if (std::lexicographic_compare(r_first, r_last, l_first, l_last) return false;
    }
    return false;
}
dffbzjpn

dffbzjpn2#

你需要做的就是创建一个自由函数operator<,它将两个vector<vector<double>>当作const&

bool operator< (const vector<vector<double>& l, const vector<vector<double>& r)
{
    // your comparison logic here...
}

相关问题