I am trying to read a file which contains the adjacency list as
1 37 79 164 15
2 123 134 10 141 13
where first number in every line is vertex and following numbers are its adjacent vertices.
This is my code to read from the file . I have been able to put a line in a string but don't know how to proceed to populate the vector.
ifstream ifs;
string line;
ifs.open("kargerMinCut.txt");
std::vector<vector <int> > CadjList(vertices);
while(getline(ifs,line)){
}
Any suggestions ?
You can use stringstream
in the sstream header.
ifstream ifs;
string line;
ifs.open("kargerMinCut.txt");
std::vector<vector <int> > CadjList(vertices);
while(getline(ifs,line)){
// transfer the line contents to line_stream.
stringstream line_stream( line );
// transfer line_stream to int variables.
int tail_node;
if ( line_stream >> tail_node ) // now do whatever you want with it.
{
int head_node;
while ( line_stream >> head_node )
CadjList[tail_node].push_back( head_node );
}
}
Use the power of STL! ;-)
std::istringstream
to create a stream from a string.
std::copy
to copy stuff from something to something else (yes, it can be that generic!).
std::istream_iterator
and std::ostream_iterator
to read and write to stream with an iterator interface, very useful in combination with std::copy
.
std::back_inserter
to use push_back
with std::copy
.
std::vector
's constructor can take iterators to initilize its content.
std::map
might be better than a std::vector
if your vertex are not a continuous range starting from 0.
Which gives something like:
// vertex -> adjacent vertices
std::map<int, std::vector<int>> map;
std::string line;
while (std::getline(ifs, line))
{
std::istringstream is(line);
std::vector<int> ns;
std::copy(std::istream_iterator<int>(is), std::istream_iterator<int>(),
std::back_inserter(ns));
assert(ns.size() > 1); // or throw something
// The first is the vertex
map[ns[0]] = std::vector<int>(ns.begin() + 1, ns.end());
}
Live example
Alternative implementation, assuming the file is not corrupt:
// vertex -> adjacent vertices
std::map<int, std::vector<int>> map;
std::string line;
while (std::getline(ifs, line))
{
std::istringstream is(line);
std::vector<int> ns;
// assuming we know for sure the file is valid
auto it = std::istream_iterator<int>(is);
auto end = std::istream_iterator<int>();
auto vertex = *(it++); // and not ++it !
map[vertex] = std::vector<int>(it, end);
}
live example
Generally speaking, <algorithm>
contains many nice functions.
Code in the while loop:
while(std::getline(ifs,line))
{
std::vector<int> temp;
std::istringstream str(line);
int n;
while ( str >> n )
{
temp.push_back(n);
}
CadjList.push_back(temp);
}