2016-07-25 7 views
1

比較可能なフィールドが多いオブジェクト間で厳密な順序付けを行うにはどうすればよいですか?複数のフィールドとの比較時に厳密な順序を指定する

はあなたが比較する必要が二つのオブジェクトxy、グッド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)もtrueです。

私は

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); 

誰かが見た目の良いアルゴリズムを持っていますか?

+2

私はあなたが何が最も重要なフィールドであるか、それより少ないものを定義する必要があると思います。注文は正確に決めるべきだと思います。基本的に、最初にチェックするプロパティは何ですか、秒は何ですか?そして第3は何ですか? –

+0

私はそれをやりたいですが、問題の性質上、比較*は各フィールドを何らかの方法で考慮しなければなりません – UmNyobe

+2

もう一つの選択肢は、3つ(または4つ、または10つ)の計算を行う関数を作成することです。あなたに一つの値を与え、*あなたが比較するものであるプロパティ。 'val_to_compare = 1 * a + 10 * b + 23 * c'のようなものです。これにより、プロパティにウェイトを付けることができます。 –

答えて

3

あなたがC++ 11以上であれば、SWOを手で書く必要なしに手に入れられる素晴らしいトリックがあります。 std::tupleを使用してメンバーをパックし、std::tupleoperator<を実装しているという事実を辞書順に並べることができます。

ですから、この

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); 
    } 
}; 

と構造体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++ 11のためのC++ 14を(前提とした場合、これは入力の手間を節約することができます返品タイプtiedを手書きで書く必要があります)。

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; 
} 

これはハード順序を提供し、要素ごとのオーバーヘッドを成長させずに気にできるだけ多くの要素に及びます。

関連する問題