Iterating over edges of a graph using range-based for

前端 未结 3 2120
礼貌的吻别
礼貌的吻别 2021-02-08 00:42

I have a representation of a graph as a std::vector> neighbors, that is, vertices are integers, and for each vertex we keep

3条回答
  •  不知归路
    2021-02-08 01:20

    I believe that your internal representation of a graph, std::vector>, is what makes the code hard to write/read. Maybe another representation (e.g. std::set>) would make your code simpler. However, it's hard to tell since we don't know exactly what are the requirements of Graph.

    Anyway, as pointed out by Zeta there's a bug in EdgeIter::operator !=(). For instance, the code below:

    int main() {
    
        Graph g(5);
        g.addEdge(0, 1);
        g.addEdge(0, 2);
    
        auto i1 = g.edges().begin();
        auto i2 = i1;
        ++i2;
        std::cout << std::boolalpha;
        std::cout << (i1 != i2) << std::endl;
    }
    

    outputs false. Hence, the code considers that i1 and i2 are not different when they clearly are.

    Update:

    It's probably obvious but here is a simpler version which uses a different representation for the graph. However, I emphasize that this may not be satisfactory depending on your requirements for Graph (which I don know):

    #include 
    #include 
    #include 
    
    typedef unsigned Vertex;
    
    class Graph {
    
    public:
    
        typedef std::pair Edge;
        typedef std::set Edges;
    
        void addEdge(Vertex u, Vertex v) {
          edges_.insert({u, v});
        }
    
        const Edges& edges() { return edges_; }
    
    private:
    
        Edges edges_;
    };
    
    int main() {
    
        Graph g;
    
        g.addEdge(1, 2);
        g.addEdge(2, 3);
        g.addEdge(1, 3);    
    
        for (auto e: g.edges())
            std::cout << e.first << ' ' << e.second << std::endl;
    }
    

提交回复
热议问题