其他分享
首页 > 其他分享> > c – 在与多个字段比较时提供严格的排序

c – 在与多个字段比较时提供严格的排序

作者:互联网

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

假设您有两个必须比较的对象x和y,每个对象有3个字段(a,b,c)

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

很好,但这提供了弱序.如果x.a< y.a和y.b< x.b,less(x,y)为真,less(y,x)也为真. 我习惯写作

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

但是一旦涉及的领域数量增加,它就开始变得非常丑陋.

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

有人有更好看的算法吗?

解决方法:

如果您使用的是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,你必须写出手工绑定的返回类型).

标签:c,algorithm,language-agnostic,boolean-logic
来源: https://codeday.me/bug/20190824/1703756.html