与多个领域进行比较时提供严格的订购

时间:2016-07-25 09:48:46

标签: c++ algorithm language-agnostic boolean-logic

如何在具有大量可比较字段的对象之间提供严格的排序?

假设您必须比较两个对象<div ui-view data-ajax-cloak></div> x,每个对象有3个字段(a,b,c)

y

很好,但这提供了弱排序。如果x.a&lt; y.a和y.b&lt; x.b,bool less(x, y) return x.a < y.a || x.b < y.b || x.c < y.c 为真,less(x,y)也是如此。

我习惯写作

less(y, x)

但是一旦涉及的字段数量增加,它就开始变得非常难看。

bool less(x, y)
  return x.a < y.a || (x.a == y.a && x.b < y.b)

有人有更好看的算法吗?

2 个答案:

答案 0 :(得分:4)

如果您使用的是C ++ 11或更高版本,那么有一个很好的技巧可以获得SWO,而无需手动编写。您可以使用std::tuple打包您的成员以及std::tuple实现operator<作为词典排序的事实。

所以你可以写这个

struct foo {
    int x, y, z;

    bool operator<(const foo& rhs) const {
        return std::tie(x, y, z) < std::tie(rhs.x, rhs.y, rhs.y);
    }
};

和struct foo将按字典顺序用x,y,z进行比较。这仍然需要写很多,所以你可以稍微改进一下

struct foo {
    int x, y, z;

    auto tied() const {
        return std::tie(x, y, z);
    }

    bool operator<(const foo& rhs) const {
        return tied() < rhs.tied();
    }
};
如果你有很多成员,这可以节省大量的输入,但是它假设是C ++ 14(对于C ++ 11,你必须手写出tied的返回类型)。

答案 1 :(得分:2)

我通常这样做:

bool operator< (type x, type y) {
    if (x.a < y.a) return true;
    if (x.a > y.a) return false;

    if (x.b < y.b) return true;
    if (x.b > y.b) return false;

    return x.c < y.c;
}

这提供了硬排序,并扩展了您关心的尽可能多的元素,而不会增加每个元素的开销。