使用一组结构,并避免一组重复的结构

时间:2018-10-10 19:20:43

标签: c++ struct graph set undirected-graph

我试图表示一个无向图。我创建了三个结构,如下所示。我在Edge结构中添加了运算符==和运算符<,希望集合可以使用它来比较元素。

struct  Node;   /* Forward references to these two types */
struct Edge;     /* that the compiler can recognize them */

/* Type: Node
 * This type represents an individual node and consists of the data of the 
 *  node and the set of edges from this node */
struct Node{
    int nodeNum;
    string data;
    set<Edge*> edges;
};


/* Type: Edge
 * This type represents an individual edge and consists of pointers to the 
 * endpoints */
struct Edge{
    Node *end1;
    Node *end2;

    // This says that edge from node 1 to node 2 and edge from node 2 to node 1 are considered the same
    bool operator==(const Edge &e) const{
        return ( (this->end1->nodeNum == e.end1->nodeNum && this->end2->nodeNum == e.end2->nodeNum) ||
                 (this->end1->nodeNum == e.end2->nodeNum && this->end2->nodeNum == e.end1->nodeNum));
    }

    // This function is used by set to order elements of edges.
    bool operator<(const Edge *e) const{
        return (this->end1 < e->end1 && this->end2 < e->end2);
    }
};


// This is a struct for graph
struct Graph{
    set<Node*> Nodes;
    set<Edge*> Edges;
    map<int, Node*> nodeMap;
};

问题:如果说的话,我从节点1到2有一条边,从2到1有一条边,我的struct声明说它们应该被认为是等效的。但是,当我将这两个边插入集合中时,会将它们都插入为两个单独的元素(即集合不知道边1-2和2-1相等)。我该怎么做才能使集合处理重复项(即仅保留这些边缘之一)。参见例如下方:

 int main(){
    // Let's make 2 nodes, node 1 and node 2
    Node* n1 = new Node;
    Node* n2 = new Node;
    n1->nodeNum=1;
    n2->nodeNum=2;

    // Let's make 2 edges 1-2 and 2-1
    Edge* e1 = new Edge;
    Edge* e2 = new Edge;
    e1->end1=n1; e1->end2=n2;
    e2->end1=n2; e2->end2=n1;

    // Now let's make a graph and put the edges in its internal set
    Graph g;
    g.Edges.insert(e1);  
    g.Edges.insert(e2);  // the set takes in both e1 and e2. If I print all elements in g.Edges, it will print both 1-2 and 2-1
    // How do I tell the set to treat e1 and e2 as equal edges so it took care of duplicates?

    return 0;
   }

1 个答案:

答案 0 :(得分:1)

std::set<T*>将创建一组存储位置,而不是一组T值。

如果要比较指向的对象,则需要提供一个自定义比较器:

struct Ptr_compare {
  template<typename T>
  constexpr bool operator()( const T* lhs, const T* rhs ) const {
    return *lhs < *rhs;
  }
};

// This is a struct for graph
struct Graph {
    set<Node*, Ptr_compare> Nodes;
    set<Edge*, Ptr_compare> Edges;
    map<int, Node*> nodeMap;
};

但是:

请注意,我编写的代码可以回答您的问题,但仍不适用于您的用例,只能将其用于非所有者指针,这绝对不是您的情况。

这不是我自己的解决方案本身的问题,而是您要完成的工作的根本问题。某些东西需要调用去重复的对象上的delete