1

複数のキーに基づいてセットを別のセットにコピーする必要があります。キーは、セット内の要素の一意性と順序をまとめて維持するために使用されます。

私のクラス:

class LaneConnector {
public:

    const Lane* getLaneFrom() const {
        return From;
    }
    const Lane* getLaneTo() const {
        return To;
    }

private:

    Lane* From;
    Lane* To;
}

私の関手:

struct MyLaneConectorSorter {
  bool operator() (const LaneConnector* rhs, const LaneConnector* lhs) const
  {

    const Lane* a = lhs->getLaneFrom();
    const Lane* b = rhs->getLaneFrom();

    bool key1 = a->getLaneID() < b->getLaneID();
    bool key2 = a->getLaneParent->ID() < b->getLaneParent->ID();
    bool key2 = a->getLaneParent->getParent->ID() < b->getLaneParent->getParent->ID(); 
    //remind you that I NEED the elements to be in ascending order of 
    //getLaneParent->getParent->ID() ,a->getLaneParent->ID() and then a->getLaneID()
    //duplicate elements are the ones which have all three keys same and need to be discarded 
    return (key1 && key2 && key3); //which dont seem to be working
  }
};

そして私のソースとオリジンセット:

const std::set<LaneConnector*> src = ..... ; //the getter give me a const version
std::set<sim_mob::LaneConnector *, MyLaneConectorSorter> dest;

そして、私がそれを埋める方法:

for(std::set<sim_mob::LaneConnector*>::iterator it = tempLC.begin(); it != tempLC.end(); it++)
{
    dest.insert(*it);//I know I can insert it right at the time of declaration, but keep it like this for now...please 
}

あなたの親切な助けは非常に高く評価されます。

4

5 に答える 5

3

operator<複数のテストを正しく行うのはかなり難しいので、これを行う私の方法をお勧めしますtuple(この場合は、関数から返された一時変数を扱っているため、make_tuple代わりにを使用します)。tie

#include <tuple>

struct MyLaneConectorSorter {
  bool operator() (const LaneConnector* lhs, const LaneConnector* rhs) const
  {
    const Lane* a = lhs->getLaneFrom();
    const Lane* b = rhs->getLaneFrom();
    auto const* pa = a->getLaneParent();
    auto const* pb = b->getLaneParent();

    return std::make_tuple(a->getLaneID(), pa->ID(), pa->getParent()->ID()) < 
           std::make_tuple(b->getLaneID(), pb->ID(), pb->getParent()->ID())
}

これは機能するはずであり、コンパイラがまだそれらを提供していない場合は、Boost からtuple取得することもできます。make_tuple

于 2012-09-25T08:52:06.760 に答える
3

キー フィールドの比較に優先順位を付ける必要があります...最も重要なフィールドが等しい場合にのみ、2 番目に重要なフィールドを比較します。それが等しい場合は、3 番目に重要なフィールドを比較します。必要に応じて true または false。したがって、これは&&操作ではありません。次のように? :、またはif-elseチェーンにする必要があります。

return lhs.key1 < rhs.key1 ? true :
       rhs.key1 < lhs.key1 ? false :
       lhs.key2 < rhs.key2 ? true :
       rhs.key2 < lhs.key2 ? false :
       ...
       false;

セットが正しく動作するためには、キーが決して等しくないことを確認する必要があります。つまり、lastfalseが実際に使用されることはありません。

于 2012-09-25T08:41:44.183 に答える
2

比較する 3 つのメンバー foo、bar、および baz がある場合、これはそれらを比較する一般的な方法です。

return lhs.foo < rhs.foo
    || lhs.foo == rhs.foo && (lhs.bar < rhs.bar
                           || lhs.bar == rhs.bar && lhs.baz < rhs.baz);

パターンが見えますか?;)

于 2012-09-25T08:49:10.263 に答える
1

並べ替えのルールを理解するのに問題がありますが、リレーションが単純なサブ並べ替えである場合、コードは次のようになります。

if (a->getLaneID() < b->getLaneID())
  return true;
else if (a->getLaneID() == b->getLaneID())
{
  if (a->getLaneParent->ID() < b->getLaneParent->ID())
    return true;
  // etc...
}
return false;
于 2012-09-25T08:42:32.200 に答える
1

あなたclass MyLaneConnectionSorterには欠陥があります。

std::set要素を順序付けできる比較クラスが必要です。したがって、比較関数はlessファンクター orと同様の動作を提供する必要がありますoperator<。つまり、a < bor a > b(これはb < a) またはa == b(これは!(a < b) && !(a > b))のいずれかです。

比較関数を使用すると、レーン (6, 5, 4) と (7, 3, 4) ((PPID, PID, ID) の形式) は等しいと見なされます。したがって、次のように比較する必要があります。

if (a->getLaneParent->getParent->ID() < b->getLaneParent->getParent->ID()) return true;
else if (a->getLaneParent->getParent->ID() > b->getLaneParent->getParent->ID()) return false;
else {
    if (a->getLaneParent->ID() < b->getLaneParent->ID()) return true;
    else if (a->getLaneParent->ID() > b->getLaneParent->ID()) return false;
    else {
        return (a->getLaneID() < b->getLaneID());
    }
}
于 2012-09-25T08:52:57.863 に答える