我是一个非常新的C ++程序员,试图实现以下代码试图找到 两个给定节点之间的所有路径(图)。它使用连接的边对和给定的节点对来计算它们之间的所有可能路径作为控制台的输入,并将给定节点对之间的所有可能路径写入控制台。算法非常有效好。但是,我想从/向txt文件读/写输入/输出。但我不能这样做。有没有人能够表明正确的方法?
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <iostream>
#include <fstream>
using namespace std;
vector<vector<int> >GRAPH(100);
inline void printPath(vector<int>path)
{
cout<<"[ ";
for(int i=0; i<path.size(); ++i)
{
cout<<path[i]<<" ";
}
cout<<"]"<<endl;
}
bool checksAdjacencyNode(int node,vector<int>path)
{
for(int i=0; i<path.size(); ++i)
{
if(path[i]==node)
{
return false;
}
}
return true;
}
int findpaths(int sourceNode ,int targetNode,int totalnode,int totaledge)
{
vector<int>path;
path.push_back(sourceNode);
queue<vector<int> >q;
q.push(path);
while(!q.empty())
{
path=q.front();
q.pop();
int lastNodeOfPath=path[path.size()-1];
if(lastNodeOfPath==targetNode)
{
printPath(path);
}
for(int i=0; i<GRAPH[lastNodeOfPath].size(); ++i)
{
if(checksAdjacencyNode(GRAPH[lastNodeOfPath][i],path))
{
vector<int>newPath(path.begin(),path.end());
newPath.push_back(GRAPH[lastNodeOfPath][i]);
q.push(newPath);
}
}
}
return 1;
}
int main()
{
int T,totalNodes,totalEdges,u,v,sourceNode,targetNode;
T=1;
while(T--)
{
totalNodes=6;
totalEdges=11;
for(int i=1; i<=totalEdges; ++i)
{
scanf("%d%d",&u,&v);
GRAPH[u].push_back(v);
}
sourceNode=1;
targetNode=4;
findpaths(sourceNode,targetNode,totalNodes,totalEdges);
}
return 0;
}
Input::
1 2
1 3
1 5
2 1
2 3
2 4
3 4
4 3
5 6
5 4
6 3
output:
[ 1 2 4 ]
[ 1 3 4 ]
[ 1 5 4 ]
[ 1 2 3 4 ]
[ 1 5 6 3 4 ]
答案 0 :(得分:0)
关于输出,您只需使用std::ofstream
并替换使用std::cout
的位置:
inline std::ostream& os printPath(std::ostream& os, vector<int>path)
{
os <<"[ ";
for(int i=0;i<path.size();++i)
{
os<<path[i]<<" ";
}
os<<"]"<<endl;
}
int main(int argc, char** argv)
{
if(argc > 1)
{
std::ofstream ofs(argv{1]);
// ...
printPath(ofs,path)
}
}
关于从文件中读取这种格式,我建议s.th.像这样:
std::ifstream ifs("MyGraphFile.txt");
while(ifs && !ifs.eof())
{
std::string line = std::string::getline(ifs);
// strip the '[' and ']' characters
line = line.substr(1,line.length() - 2);
std::istringstream iss(line);
std::vector<int> currentInputs;
int value;
while(iss >> value)
{
currentInputs.push_back(value);
}
GRAPH.push_back(currentInputs);
currentInputs.clear();
}
答案 1 :(得分:0)
我认为使用Boost Graph Library会很轻松。而且,在某种程度上,它是。
解析输入文件:
std::vector<std::pair<int, int>> parse_input(const char* const fname, int& min_vertex, int& max_vertex)
{
std::vector<std::pair<int, int>> data;
min_vertex = std::numeric_limits<int>::max();
max_vertex = std::numeric_limits<int>::min();
std::ifstream ifs("input.txt");
std::string line;
while (std::getline(ifs, line))
{
int a, b;
if (std::istringstream(line) >> a >> b)
{
data.emplace_back(a, b);
if (a>b) std::swap(a,b);
min_vertex = std::min(min_vertex, a);
max_vertex = std::max(max_vertex, b);
}
else throw "oops";
}
return data;
}
然后,程序的简单存根应该是:
struct my_visitor : boost::default_bfs_visitor
{
template < typename Vertex, typename Graph >
void discover_vertex(Vertex const& u, const Graph & g) const
{
std::cout << "discover_vertex: " << u << "\n";
}
};
int main()
{
typedef boost::adjacency_list<> Graph;
typedef Graph::vertex_descriptor Vertex;
int min_vertex, max_vertex;
auto const lines = parse_input("input.txt", min_vertex, max_vertex);
const Graph G(begin(lines), end(lines), max_vertex+1);
print_graph(G);
const auto source = vertex(min_vertex, G);
breadth_first_search // visit ... needs explicit ColorMap
(G, source, boost::visitor(my_visitor()));
}
这会编译并运作, see it live on Coliru 。
但是,BFS默认只搜索所有顶点一次(使用颜色编码):
0 -->
1 --> 2 3 5
2 --> 1 3 4
3 --> 4
4 --> 3
5 --> 6 4
6 --> 3
discover_vertex: 1
discover_vertex: 2
discover_vertex: 3
discover_vertex: 5
discover_vertex: 4
discover_vertex: 6
我们实际上需要使用breadth_first_visit
代替,同时将每个顶点的颜色保留为WHITE,以生成所有路径。
可悲的是,我没时间试图了解如何向breadth_first_visit
提供合适的自定义ColorMap
。
如果仅用于输入解析,我希望这会有所帮助。