【问题标题】:How to use self-defined structure in C++ Map如何在 C++ Map 中使用自定义结构
【发布时间】:2012-04-09 18:00:41
【问题描述】:

我想用一个C++的map结构,比如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&lt;DFSCode&gt;PDB的数据,因为一个vector&lt;DFSCode&gt;可能有很多PDB,我想用vector&lt;PDB&gt;来存储它们。 我想做的是:

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&lt;DFSCode&gt;包含许多PDB”的期望?

第二个问题是:我知道我必须实现一个类似的map方法,因为我使用vector&lt;DFSCode&gt;作为我的key,但我不知道如何实现。我试着写一个。但似乎不能满足我对“一个vector&lt;DFSCode&gt; 包含许多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
    }
};

【问题讨论】:

  • oohhhh 继承自 vector.... :(
  • 你的意思是这是一个糟糕的结构吗? :(
  • 为什么不给DFS添加一个合适的构造函数来获取你想要的参数,并删除自定义的push_back
  • STL 容器没有虚拟析构函数,仅使用指向这些类的指针是不可能正确清理它们的。见this answer
  • 你的意思是我不能使用candidate[tempdfscodeList].push_back(temppdb);??你能指出错误吗?谢谢:)

标签: c++ data-structures collections vector map


【解决方案1】:

DFSCode 的向量可以包含多个DFSCode。由于DFSCode 可以 包含很多DFSDFSCode 的向量可以包含很多很多DFS

关于您的代码:一些建议:

  • 使用 `push_back` 和 `pop_back`,而不是 `resize`。更多 惯用语。你的函数 `push` 应该开始: push_back(DFS()); back().from() = 从; ...
  • 给 `DFS` 一个构造函数,它接受它需要的参数: DFS::DFS(int from, int to, int fromLabel, int eLabel, int toLabel) : 从( 从 ) , 到 ( 到 ) , 来自标签(来自标签) , 电子标签(电子标签) , toLabel( toLabel ) { } 然后 `push` 变得很简单: push_back(DFS(从,到,从标签,电子标签,到标签));
  • 不要从 `std::vector` 继承。使其成为数据成员。

关于您关于订购功能的问题, std::vector&lt;DFSCode&gt; 基本上是一个二维结构。这 可以通过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 );
    }
};

编辑:

有一点我忘了提。有了上面的对比 运算符,向量中项目的顺序很重要。如果这是 不可接受,那么您可能最终必须对元素进行排序 首先(临时)。

【讨论】:

  • 什么是'lexicographical_sort'?这似乎是一种算法,而不是 C++ 中的 i 函数。
  • @Mr.mr。不是所有的 STL 算法都实现为(模板化)函数吗?
  • @Mr.mr。它是标准库中的一个函数模板。它是为这类事情设计的;如果第一个序列“小于”第二个序列,则返回 true,因为“小于”由它的第五个参数定义的特定元素(或 std::less,如果没有第五个参数)。
  • 也许你的意思是 std::lexicographical_compare?
  • @juanchopanza 是的。当时我正在考虑进行排序,结果漏掉了这个名字(即使我有相关的页面来自我——我永远无法不看就拼写字典)。我会更正我的帖子。谢谢。
【解决方案2】:

第一个问题是:上面的代码是否满足我对“一个向量包含多个PDB”的期望?

使用multimap 而不是mapmap 只能有一个键值。它类似于 一对一 关系。 multimap 一个键可以有多个值。

你不需要像 antonio 建议的那样继承 DFScode。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    相关资源
    最近更新 更多