2013-07-20 53 views
1

我是一个相当新的C++程序员,试图实现以下代码,试图找到两个给定节点(图)之间的所有路径。它使用连接的边对和给定的节点对来计算将它们之间的所有可能路径作为控制台的输入,并将给定节点对之间的所有可能路径写入控制台。该算法工作得非常好。但是,我想读/写输入/输出到/ txt文件。但我做不到。有没有人展示正确的方式?从C++的文本文件读取/写入

#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 ] 
+1

请您详细说明您的问题。编译器错误,程序崩溃,意外的行为,... –

+0

问题是我想只使用2个变量来分配输入。在这种情况下,如果我使用txt文件,我不能通过输入的第二行,因为我要在第二行使用相同的变量。看起来,我需要一个循环,但不知道如何实现它。 – zaratushtra

+0

输入和输出是显示您想要的内容,还是显示您获得的内容但与您想要的不同? – lurker

回答

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) 
    } 
} 

关于从文件中读取此格式,我建议某事物像这样:

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(); 
} 
+0

对不起,我试过了,但它似乎不工作 – zaratushtra

+0

@zaratushtra我只是试图给一个样本,没有真正编译,我认为你会推断它并融入到你的代码。什么不适合你,特别是? –

0

我认为这将是一个轻松与Boost图库。而且,在某种程度上,它是。

解析输入文件:

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代替,同时使色彩在白色每个顶点,生成所有路径。

不幸的是,我耗尽时间试图看看如何喂养breadth_first_visit一个合适的自定义ColorMap

我希望这有助于,如果仅用于输入解析。