Чтение графа из потока в вектор списка смежности - PullRequest
0 голосов
/ 31 января 2020

Я пытаюсь создать граф в виде списка смежности, читая из файла, показанного ниже

Здесь первая строка - количество вершин. В приведенном ниже примере мы имеем 12 вершин, а в следующих строках, например, 1 2 3 4 означает, что вершина 1 имела ребра до 2, 3 и 4.

12
1 2 3 4
2 1 5 6
3 1 6
4 1 7
5 2 9 10
6 2 3
7 4 8 
8 4 7
9 5 10
10 5 9
11 12
12 11

C ++ программа

#include <iostream>
#include <fstream>
#include <strstream>
#include <sstream> // for std::getline

#include "Graph.h"

using namespace std;

// Note: vector index is will match the vertex id.
std::vector <std::vector<std::pair<int, int> > > vecIdxedGraph;


void storeEdges(const string& strEdges) {
    std::istringstream iss(strEdges);
    int FromVertex = 0;
    iss >> FromVertex;

    std::cout << "From Vertex " << FromVertex << endl;

    vector<pair<int, int>> edges;
    string toVertex;
    while (std::getline(iss, toVertex, ' ')) {
        std::cout << "to Vertex " << toVertex << " ";
        edges.push_back(std::make_pair(atoi(toVertex.c_str()), 0));
    }
    std::cout << std::endl;
    vecIdxedGraph.push_back(edges);
    return;
}

void printGraph() {
    for (int i = 0; i < vecIdxedGraph.size(); i++) {
        cout << "Vertex " << i + 1 << " ";
        for (int j = 0; j < vecIdxedGraph[i].size(); j++) {
            cout << vecIdxedGraph[i][j].first << " ";
        }
        cout << endl;
    }
}
int main() {

    // create Graph
    ifstream inFile("Graph.txt");
    if (!inFile) {
        cout << "Open input file failed." << endl;
    }

    // Set input stream to file.
    std::streambuf* pOldCinBuf = cin.rdbuf();
    cin.set_rdbuf(inFile.rdbuf());

    int iNumberOfNodes;
    cin >> iNumberOfNodes;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cout << "Number of nodes in graph are: " << iNumberOfNodes << endl;

    vecIdxedGraph.reserve(iNumberOfNodes);



    for (int iVertexId = 1; iVertexId <= iNumberOfNodes; iVertexId++) {
        std::string vertIdDetails;
        std::getline(cin, vertIdDetails);
        // cout << (vertIdDetails.c_str()) << endl;
        // parse line and store to the vector.
        storeEdges(vertIdDetails);
        // cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }

    printGraph();
    return 0;
}

Ниже выводится

Vertex 1 0 2 3 4
Vertex 2 0 1 5 6
Vertex 3 0 1 6
Vertex 4 0 1 7
Vertex 5 0 2 9 10
Vertex 6 0 2 3
Vertex 7 0 4 8
Vertex 8 0 4 7
Vertex 9 0 5 10
Vertex 10 0 5 9
Vertex 11 0 12
Vertex 12 0 11

Хотите удалить 0. Я думаю, 0 идет из пустого пространства при чтении строки

while (std::getline(iss, toVertex, ' '))

Я не понимаю, как ее очистить.

Другой вопрос, как я могу создать вектор с построением по умолчанию, чтобы я мог использовать

vecIdxedGraph [FromVertex] = ..., а не push_back.

Пожалуйста, помогите

1 Ответ

1 голос
/ 31 января 2020

Похоже, ты слишком усложняешься. Вам просто нужно, что-то вроде следующего.

// Some handy names
using Pair = std::pair<int, int>;
using Graph = std::vector<std::vector<Pair>> ;

// The stream handle
std::ifstream fileHandle("Graph.txt");

size_t iNumberOfNodes  = 0;

// 1. Get # of Vertices
fileHandle >> iNumberOfNodes;

// 2. Create a graph, pre allocate the # of vertices
// One node extra since your vertices starts from 1
Graph g{iNumberOfNodes + 1, std::vector<Pair>{}}; 

std::string lineStr;
int currNode = 0, vertex;
// 3. Iterate over file, reading line by line
while ( std::getline(fileHandle, lineStr) ) {
   std::stringstream ss{lineStr};
    ss >> currNode;
    while ( currNode != 0 && ss >> vertex ) {
        g[currNode].emplace_back( vertex, 0 ) ; // weight = 0;
    }   
 }

Все готово! Demo Here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...