解析图形文件使用字符串流c++

parse graph file using string stream c++

本文关键字:字符串 c++ 图形 文件      更新时间:2023-10-16

我需要解析这种形式的图形文件:

5
0 1 0.2 3 10.1 4 0.5 -1
1 0 1.5 -1
2 1 100.0 3 50.2 -1
3 -1
4 1 10.5 2 13.9 -1

第一行为节点数。从第二行开始,

 0 1 0.2 3 10.1 4 0.5 -1

0是源节点,1是它到达的节点,0.5是边的权值。-1表示行结束

我创建了一个图形类:

#ifndef GRAPH_H
#define GRAPH_H
#include <vector>
#include <iostream>
class Graph{
 public:
    explicit Graph(int size=0) : vertices_(size) { };
    void resize(int size){
        vertices_.resize(size);
        empty();
    }
    void insert(int v, int n, double w){
        Vertex* tmp = new Vertex{ n, w, nullptr }
        cout << " inserting!";
        end(v)->next = tmp;
    }
    void empty(){
        for(int i=0;i<vertices_.size();i++)
            vertices_[i] = new Vertex{i,0,nullptr}
    }
    void print() { 
        for(auto& v : vertices_){
            Vertex* tmp = v;
            cout<< " Node " << v->node << " has edges to: n"
            while(tmp->next != nullptr){
                cout<< "  node " << tmp->node << " with weight " << tmp->weight<<endl;
            }
        cout<<endl;
        }
    }
 private:   
    struct Vertex{ // struct for vertices of graph
        int node;
        double weight;
        Vertex* next;
        Vertex (int n, double w, Vertex* v) 
    : node{ n }, weight{ w }, next{ v } { }
    };
    vector<Vertex*> vertices_;
    Vertex* end(int v){
        Vertex* tmp = vertices_[v];
        while(tmp->next != nullptr)
            tmp = tmp->next;
        return tmp;
    }
};
#endif

到目前为止,我有这个解析器:(所有变量都是适当的类型)

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <string>
#include "graph.h"
using namespace std;
int main(int argc, char** argv) {
    if(argc<3){
        cout<<"Usage: " << argv[0] << " <graph file> <starting vertex>n";
        return 0;
    }   
    bool first = true;      // true until the first line is read (flow control)
    stringstream parse;     // stringstream for easy parsing & conversion of strings
    int n, s;               // holds the nodes for inserting
    double w;               // holds the weights for edges
    string line;            
    ifstream graph1(argv[1]);
    Graph g;
    while(getline(graph1,line)){
    if(first){
        n=stoi(line);
        g.resize(n);
        first = false;
    } else {
        parse << line;
        first = true;
        while(getline(parse,line,' ')&&line != "-1"){
            if(first){
                parse >> s;
                g.insert(s,s,0)
                first = false;
            } 
            parse >> n >> w;
            cout << s << " " << n << " " << w <<endl;
            g.insert(s,n,w);
        }
    }
}

,但当i print()时,我得到一个segfault。我做错了什么?

您忘记添加temp变量

#include <bits/stdc++.h>
using namespace std;
class Graph {
    public:
        explicit Graph(int size=0) : vertices_(size) { };
    void resize(int size){
        vertices_.resize(size);
        empty();
    }
    void insert(int v, int n, double w){
        end(v)->next = new Vertex{ n, w, nullptr };
        cout << " inserted! " << endl;
    }
    void empty(){
        for(int i = 0; i < vertices_.size(); i++)
            vertices_[i] = new Vertex{ i, 0, nullptr};
    }
    void print() { 
        for(auto& v : vertices_){
            Vertex* tmp = v;
            cout<< " Node " << v->node << " has edges to: n";
            while(tmp->next != nullptr) {
                if(tmp->node != v->node)
                    cout<< "  Node " << tmp->node << " with weight " << tmp->weight<<endl;
                tmp = tmp->next; // You forgot this line
            }
        cout<<endl;
        }
    }
 private:   
    struct Vertex{ // struct for vertices of graph
        int node;
        double weight;
        Vertex* next;
        Vertex (int n, double w, Vertex* v) 
    : node{ n }, weight{ w }, next{ v } { }
    };
    vector<Vertex*> vertices_;
    Vertex* end(int v){
        Vertex* tmp = vertices_[v];
        while(tmp->next != nullptr)
            tmp = tmp->next;
        return tmp;
    }
}g;

int main()
{
    int N,x,y;
    double w;
    cin >> N;
    g.resize(N);
    for(int i = 0; i < N; i++)
    {
        cin >> x;
        while(cin >> y, y != -1)
        {
            cin >> w;
            cout << "Edge from " << x << " to " << y << " with cost " << w << endl;
            g.insert(x,y,w);
        }
    }
    g.print();
}

读取文件:

int main()
{
    ifstream myfile("in.txt");
    if(myfile.is_open())
    {
        int N,x,y;
        double w;
        myfile >> N;
        for(int i = 0; i < N; i++)
        {
            myfile >> x;
            while(myfile >> y, y != -1)
            {
                myfile >> w;
                cout << "Edge from " << x << " to " << y << " with cost " << w << endl;
            }
        }
        myfile.close();
    }
    else 
        cout << "Unable to open file"; 
    return 0;
}

你应该忽略行,只读取整数和双精度…

int n; f >> n;
for (int i=0; i<n; i++) {
    int v; f >> v;
    assert(v == i);
    int other; f >> other;
    while (other != -1) {
        double weight; f >> weight;
        add_edge(v, other, weight);
        f >> other;
    }
}

这里假设没有错误检查