【问题标题】:Confusion in creating a directed graph in C++在 C++ 中创建有向图时的困惑
【发布时间】:2013-03-03 19:31:12
【问题描述】:

我试图通过读取一个文本文件来创建一个有向图,其中每行有两列,第一列是尾顶点,第二列是头顶点。目前只是为了测试我的代码是否有效,我正在尝试填充图表并将其打印出来。

我在每次插入节点后打印我的图表。图形打印工作正常,直到我插入第三个节点“4”,之后第一个节点从 1 变为 0。我不知道为什么。我想知道将节点指针存储在边缘是否是个好主意。我这样做是因为我已经在“节点”向量中有节点信息,因此不想复制它。

输入测试文件:

1 2
4 5

我的数据结构是: node:保存节点id和布尔变量nodedirty edge:保存指向尾节点和头节点的指针 图:保存所有节点和边的向量

输出:

Pushing :1
print called
Nodes are:
1

Pushing :2
print called
Nodes are:
1
2

Pushing :4
print called
0(0) --> 2(0)     // Problem this should have been 1(0) --> 2(0)
Nodes are:
1
2
4



#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <sstream>

using namespace std;

class node {
public:
    node() {}
    node(int _nodeId, bool dirty);
    int nodeId;
    bool dirty;
    void operator=(node rhs);
    bool operator==(node rhs);
};

class edge {
public:
    edge(node *_startNode, node *_endNode): startNode(_startNode), endNode(_endNode) {}
    node *startNode, *endNode;
};



node :: node(int _nodeId, bool _dirty) {
    nodeId = _nodeId;
    dirty = _dirty;
}

void node :: operator=(node rhs) {
    this->dirty = rhs.dirty;
    this->nodeId = rhs.nodeId;
}

bool node :: operator==(node rhs) {
    if (this->nodeId == rhs.nodeId) {
        return true;
    }
    return false;
}



class graph {
public:
    void print();
    void addEdge(node startNode, node endNode);
    void addNode(node n);
    void dfs(node s);
private:
    vector<edge> edges;
    vector<node> nodes;
};

void graph :: addNode(node n) {
    // only add this node if it does not exist in the graph
    if (find(nodes.begin(), nodes.end(), n) == nodes.end()) {
        //print();
        cout <<  "Pushing :"<<n.nodeId<<endl;
        nodes.push_back(n);
    }
    print();
    cout << endl;
}

void graph :: dfs(node s) {
    // Search node s and mark it as dirty


}
void graph :: print() {
    cout << "print called\n";
    vector<edge>::iterator itr = edges.begin();
    while (itr != edges.end()) {
        cout << itr->startNode->nodeId << "("<< itr->startNode->dirty<<") --> ";
        cout << itr->endNode->nodeId << "("<< itr->endNode->dirty<<")"<<endl;
        ++itr;
    }

    cout << "Nodes are:\n";
    for (int i=0; i< nodes.size(); ++i) {
        cout << nodes.at(i).nodeId << endl;
    }
}

void graph :: addEdge(node startNode, node endNode) {
    vector<node>::iterator itrStartNode;
    itrStartNode = find(nodes.begin(), nodes.end(), startNode);
    vector<node>::iterator itrEndNode;
    itrEndNode = find(nodes.begin(), nodes.end(), endNode);
    edge e(&(*itrStartNode), &(*itrEndNode));
    edges.push_back(e);
}


int main(int argc, char *argv[]) {
    graph g;
    // Read the file here
    ifstream file;
    file.open("test.txt", ios::in);
    string line;
    while (getline(file, line)) {
        int startNodeId, endNodeId;
        istringstream is(line);
        is >> startNodeId >> endNodeId;
        node startNode(startNodeId, false);
        node endNode(endNodeId, false);
        g.addNode(startNode);
        g.addNode(endNode);
        g.addEdge(startNode, endNode);
    }
    file.close();
    g.print();
    return 0;
}

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    您正在创建临时变量,例如

            node startNode(startNodeId, false);
            node endNode(endNodeId, false);
    

        edge e(&(*itrStartNode), &(*itrEndNode));
    

    并将指向临时实例的指针存储到您的容器中,例如

        edge e(&(*itrStartNode), &(*itrEndNode));
        edges.push_back(e);
    

    一旦您退出创建这些实例的本地范围(while 循环或addEdge 方法),存储这些实例的堆栈内存将被程序收回以在其他地方使用。但是,您的 指针 仍然指向有效的内存地址(是否被程序取回),因此,可能仍然指向看似有效的数据。这可能就是正在发生的事情,为什么您会看到看似有效但不正确的顶点。

    使用new 运算符创建在循环和函数的本地范围之外持续存在的实例,并适当地清理它们(通过delete)。

    【讨论】:

    • 我想我明白你在说什么......但我无法让它工作:)。我更改了我的 addNode 和 addEdge 程序来创建新的节点和边,如下所示:node *nn = new node; nn-&gt;nodeId = n.nodeId; nn-&gt;dirty = n.dirty; nodes.push_back(*nn); 和类似的 addEdge:edge *e = new edge; e-&gt;startNode = &amp;(*itrStartNode); e-&gt;endNode = &amp;(*itrEndNode); edges.push_back(*e); 但它不能解决同样的问题!
    • 好的...我想通了...在 addEdgeaddNode 中使用 new 运算符将无济于事,因为一旦 fn 调用完成,这些 procs 中定义的变量就会丢失.因此这需要在main 内完成。感谢您的帮助!
    猜你喜欢
    • 2012-01-05
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    • 2011-09-21
    相关资源
    最近更新 更多