如何从输入文件接受图形

时间:2017-05-17 12:24:12

标签: c++ graph stl

我接受输入文件中的无向加权图。文件包含200个节点 我写了这样的代码。

typedef pair<int, int> ipair;     
class Graph
{
    int V;
    list< pair <int, int> > *adj;

    public:

    Graph(int V);     
};

Graph::Graph( int V)
{
    this-> V = V;
    adj = new list<ipair>[V];
}

bool Graph :: read_file()
{
   const long int N = 1000000;

   std::ifstream infile("Dijkstra.txt");
   if(!infile.is_open()) return false;
   std::string line;

   int i = 0;
   while ( i < N && getline(infile, line) )
   {
      std::istringstream str(line);
      int u;

      str >> u;
      if ( u > N )
      {
         // Problem.
         abort();
      }

      int v;
      int w;
      while ( str >> v >> w)
      {
         adj[u].push_back(make_pair(v,w));
      }
      ++i;
   }
}

int main()
{
    Graph g(200);
    g.read_file();

    g.print_graph();
    return 0;
}      


I/P file :      

1   80,982  163,8164    170,2620    145,648 200,8021    173,2069    92,647  26,4122 140,546 11,1913 160,6461    27,7905 40,9047 150,2183    61,9146 159,7420    198,1724    114,508 104,6647    30,4612 99,2367 138,7896    169,8700    49,2437 125,2909    117,2597    55,6399      

2   42,1689 127,9365    5,8026  170,9342    131,7005    172,1438    34,315  30,2455 26,2328 6,8847  11,1873 17,5409 157,8643    159,1397    142,7731    182,7908    93,8177        

节点1通过权重982
连接到节点80 节点1通过权重8164

连接到节点163

节点2通过权重1689与节点42连接 节点2通过权重9365
连接到节点127 等.....
现在有了这个,我可以接受节点1连接到节点80,重量为982(1 80,982),但是与节点1连接的剩余节点呢? 即如何使循环接受v和w ??

2 个答案:

答案 0 :(得分:2)

我认为您可以使用list< pair <int, int> > *adj代替vector<list< pair <int, int> >> adj在Graph类中存储数据。

我稍微修改了你的程序,以存储与节点相关的所有数据对。

#include <iostream>
#include <utility>
#include <list>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <vector>

using namespace std;

typedef pair<int, int> ipair;
class Graph
{
  int V;
  vector<list< pair <int, int> >> adj;

public:
  bool read_file();
  void print_graph();
  Graph(int V);
};

Graph::Graph( int V)
{
  this-> V = V;
  adj.reserve(V);
}

bool Graph:: read_file()
{
  const long int N = 1000000;

  std::ifstream infile("Dijkstra.txt");
  if(!infile.is_open()) return false;
  std::string line;

  int i = 0;
  while ( i < N && getline(infile, line) ) {
    std::istringstream str(line);
    int u;

    str >> u;
    if ( u > N ) {
      // Problem.
      abort();
    }

    int v;
    int w;
    char c;
    while ( str >> v >> c >> w) {
      if (u <= (int)adj.size()) { // index (u-1) exists
        auto list = adj[u-1]; // get the existing list
        list.push_back(make_pair(v,w)); // add new data
        adj[u-1] = list; // store it the same index
      } else { // index (u-1) doesn't exist
        list<ipair> list; // create a new list
        list.push_back(make_pair(v,w)); // store the values
        adj.push_back(list); // add it in the vector
      }
    }
    ++i;
  }
  return true;
}

void Graph::print_graph() {
  int node = 1;
  for (auto& x : adj) {
    cout << "from node: " << node++ << endl;
    for (auto it = begin(x); it != end(x); ++it) {
      cout << it->first << " " << it->second << "\n";
    }
  }
}

int main() {
  Graph g(200);
  g.read_file();

  g.print_graph();
  return 0;
}

答案 1 :(得分:0)

你可以正则表达式匹配,。

e.g。

std::regex pairs_regex("(\d+),(\d+)");
auto pairs_it = std::sregex_iterator(line.begin(), line.end(), pairs_regex);
auto pairs_end = std::sregex_iterator();
for(;pairs_it != pairs_end; ++pairs_it)
{
    std::string v = pairs_it->str(1);
    std::string w = pairs_it->str(2);
    adj[u].push_back(make_pair(std::stoi(v), std::stoi(w)));
}

N.B。如果adjstd::容器而不是原始数组,那么会更安全。循环体将填充list<pair<int, int>> temp,然后填充adj.emplace_back(std::move(temp))