【问题标题】:STL map Custom Key Class [default constructor]STL 映射自定义键类 [默认构造函数]
【发布时间】:2015-01-16 18:12:48
【问题描述】:

我有一个带有如下节点类的图形实现

class Node {
public:
    Node() : idx(0), volume(1.0), futureVol(1.0), isCoarse(false) { }
    Node(index n) : idx(n), volume(1.0), futureVol(1.0), isCoarse(false) { }
    Node(const Node& a) : idx(a.idx), volume(a.volume), futureVol(a.futureVol), isCoarse(a.isCoarse) { }

    ...

    bool operator<(const Node& n) const {
        return futureVol > n.futureVol;
    }
    bool operator==(const Node& n) const {
        return idx > n.idx;
    }

    Node& operator=(const Node& node){
        if(this != &node){
            futureVol = node.futureVol;
            volume = node.volume;
            isCoarse = node.isCoarse;
            idx = node.idx;
        }
        return *this;
    }

private:
    index idx;
    double volume;
    double futureVol;
    bool isCoarse;
};

以及具有以下实现的图表:

class Graph{
private:
    std::map<Node,std::vector<Node>> edges;
    std::map<index, std::map<index, edgeweight>> edgeWeights;
    std::map<index, Node> nodes;
    Graph(const Graph& g);
    Graph& operator=(const Graph& g);
    count numNodes;
public:
    Graph(count& n); //default
    ~Graph(); //destructor
    Graph(std::vector<Node>&);
    void print();
    const std::vector<Node> neighbors(const index& idx) const;
    const std::vector<Node> coarseNeighbors(const index& idx) const;
    void addEdge(index &node1, index &node2, edgeweight& weight);
    void addEdges(std::map<index, std::map<index, edgeweight> >& e );
    edgeweight weight(const index& idx, const index& idx2) const;
    edgeweight weightedDegree(const index& idx) const;
    count degree(const index& idx) const;
    std::map<index, Node>& getNodes(){return nodes;}
    const count getSize() const { return numNodes; }
};

#endif

还有 Graph.cpp:

#include "graph.h"
#include <algorithm>

Graph::Graph(count& n): 
edges(),
edgeWeights(),
nodes(),
numNodes(n)
{
    for(index i=0; i<numNodes;i++){
        Node n(i);
        nodes[i] = n;   
    }
}
...
void Graph::addEdge(index& n1, index& n2, edgeweight& weight){

    edgeWeights[n1][n2]= weight;
    edgeWeights[n2][n1]= weight;
    edges[nodes[n1]].push_back(nodes[n2]);
    edges[nodes[n2]].push_back(nodes[n1]);
}
...

问题是每当我添加新边缘时。调用 Node 的默认构造函数,我最终将 0 作为节点 ID,而不是传递给 addEdge 的原始节点,例如 addEdge(1,2,4.0) 会将边 0 2 添加到图中。任何帮助将不胜感激。

我尝试编写如下自定义哈希函数,但没有帮助:

namespace std
{
    template <>
    struct hash<Node>
    {
        size_t operator()(const Node& n) const
        {
            return (hash<float>()(n._index()) >> 1);
        }
    };
}

【问题讨论】:

  • 你确定所有与index关联的Nodes都是在你调用AddEdge的时候创建的,因为map的operator[],返回的是提供的key对应的值还是插入一个新的(key, newvalue),其中newvalue是默认构造的。
  • 我会看看emplace()。您应该能够使用它将对象添加到您的地图并按照您的意愿构建它们。
  • @NetVipeC 是的,我确认我的所有节点都已创建。我也明白一个新值是默认构造的。但是,在这种情况下,它默认创建一个新密钥。
  • 你所有的节点都是等价的(就map&lt;Node, ...&gt;而言)。它们都具有相同的 futureVol 值,因此没有一个比其他任何一个都少。 edges[nodes[n1]]edges[nodes[n1]] 都引用同一个映射条目。
  • @IgorTandetnik 这几乎解决了它。我把它改成索引。如果您将该评论作为答案发布,我将接受并对其进行投票。谢谢。

标签: c++ graph stl stdmap


【解决方案1】:

回想一下std::map 使用operator&lt;,而不是operator==。只要!(key1 &lt; key2) &amp;&amp; !(key2 &lt; key1),它就认为两个键是等效的。

您的Node::operator&lt;futureVol 进行比较,除了1.0 的默认值之外,您从未将其设置为任何其他值,因此就std::map&lt;Node, ...&gt; 而言,您的程序创建的所有节点都彼此等效。因此,edges 地图只有一个条目。当你写

edges[nodes[n1]].push_back(nodes[n2]);
edges[nodes[n2]].push_back(nodes[n1]);

两个语句都更新同一个条目。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-30
    • 2015-02-25
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多