Как использовать самоопределенную структуру в C ++ Map - PullRequest
0 голосов
/ 26 марта 2012

Я хочу использовать структуру карты C ++, такую ​​как map<vector<DFSCode>, vector<PDB>> candidate, DFSCode и PDB - две структуры, которые я определяю.

class DFS {
public:
    int from;
    int to;
    int fromlabel;
    int elabel;
    int tolabel;
    DFS(): from(0), to(0), fromlabel(0), elabel(0), tolabel(0) {};
};

struct DFSCode: public vector <DFS> {
public:
    void push (int from, int to, int fromlabel, int elabel, int tolabel)
    {
        resize (size() + 1);
        DFS &d = (*this)[size()-1];

        d.from = from;
        d.to = to;
        d.fromlabel = fromlabel;
        d.elabel = elabel;
        d.tolabel = tolabel;
    }
    void pop () { resize (size()-1); }
};

class PDB {
public:
    unsigned int tid;
    unsigned int gid;
    void push(int did, int vid, int vlabel)
    {
        tuple[did].vid = vid;
        tuple[did].vlabel = vlabel;
    }
    PDB(): tid(0), gid(0), tuple(0) {};
};

Я сгенерирую много данных, которые содержат vector<DFSCode> и PDB, поскольку у одного vector<DFSCode> может быть много PDB, я хочу использовать vector<PDB> для их хранения.Я хочу сделать следующее:

vector<DFSCode> tempdfscodeList;
PDB             temppdb;
map<vector<DFSCode>, vector<PDB>> candidate;
for each `vector<DFSCode>` and `PDB` pair I generate
    candidate[tempdfscodeList].push_back(temppdb);

Первый вопрос: удовлетворяет ли приведенный выше код моим ожиданиям, что «один vector<DFSCode> содержит много PDB»?

Второй вопрос:Я знаю, что должен реализовать сопоставимый метод отображения, поскольку я использую vector<DFSCode> в качестве ключа, но я не знаю, как реализовать.Я пытаюсь написать один.Но, похоже, мои ожидания о том, что «один vector<DFSCode> содержит много PDB», меня не устраивают, кто-нибудь может мне помочь?:)

class dfscodeListCompare {  // compare vector<DFSCode>
public:
    bool operator() (const vector<DFSCode> &c1, const vector<DFSCode> &c2) const
    {
        for(int I = 0; I < c1.size(); I++) {
            if(c1[I].size() == c2[I].size()) {  // the size must be the same
                for(int j = 0; j < c1[I].size(); j++) {
                    if((c1[I][j].from != c2[I][j].from) || (c1[I][j].to != c2[I][j].to) || (c1[I][j].fromlabel != c2[I][j].fromlabel) || (c1[I][j].elabel != c2[I][j].elabel) || (c1[I][j].tolabel != c2[I][j].tolabel))
                        return false;   // if there exist one different
                }
            }
            else
                return false;
        }
        return true;    // pass all condition
    }
};

Ответы [ 2 ]

3 голосов
/ 26 марта 2012

Вектор DFSCode может содержать множество DFSCode. Так как DFSCode может содержит много DFS, вектор DFSCode может содержать много, много DFS.

Что касается вашего кода: некоторые предложения:

  • Используйте `push_back` и` pop_back` вместо `resize`. Это намного больше идиоматическое. Ваша функция `push` должна запуститься:
        push_back( DFS() );
        back().from() = from;
        ...
    
  • Дайте `DFS` конструктор, который принимает необходимые аргументы:
        DFS::DFS( int from, int to, int fromLabel, int eLabel, int toLabel )
            : from( from )
            , to( to )
            , fromLabel( fromLabel )
            , eLabel( eLabel)
            , toLabel( toLabel )
        {
        }
    
    Тогда `push` становится просто: push_back (DFS (от, до, от Label, eLabel, toLabel));
  • Не наследуйте от `std :: vector`. Сделайте это членом данных.

Что касается вашего вопроса о функции заказа, std::vector<DFSCode> в основном двумерная структура. это может быть элегантно обработан с помощью lexicographical_compare:

struct CompareDFSCode
{
    bool operator()( DFS const& lhs, DFS const& rhs ) const
    {
        if ( lhs.from != rhs.from )
            return lhs.from < rhs.from;
        else if ( lhs.to != rhs.to )
            return lhs.to < rhs.to;
        else if ( lhs.fromLabel != rhs.fromLabel )
            return lhs.fromLabel < rhs.fromLabel;
        else if ( lhs.eLabel != rhs.eLabel )
            return lhs.eLabel < rhs.eLabel;
        else
            return lhs.toLabel < rhs.toLabel;
    }

    bool operator()( DFSCode const& lhs, DFSCode const& rhs ) const
    {
        return std::lexicographical_compare(
            lhs,begin(), lhs.end(),
            rhs.begin(), rhs.end(),
            *this );
    }

    bool operator()(
            std::vector<DFSCode> const& lhs,
            std::vector<DFSCode> const& rhs ) const
    {
        return std::lexicographical_compare(
            lhs.begin(), lhs.end(),
            rhs.begin(), rhs.end(),
            *this );
    }
};

EDIT:

Один важный момент, который я забыл упомянуть. С приведенным выше сравнением оператор, порядок элементов в векторах является значительным. Если это не приемлемо, тогда вам, вероятно, придется в конечном итоге сортировать элементы первая (временная).

0 голосов
/ 26 марта 2012

Первый вопрос: удовлетворяет ли приведенный выше код моему ожиданию, что «один вектор содержит много PDB»?

Перейти на multimap вместо map. map может иметь только одно значение для ключа. Это как отношение один к одному . multimap может иметь много значений для одной клавиши.

Вам не нужно наследовать код DFS, как предложил Антонио.

...