Origin
I was trying to build a graph data structure and I want to use a .txt file to initialize the graph. The first time it runs successfully. But after I added another DAG.txt
file, exception happened.
Information
- OS: Windows 10
- Develop Environment: VS Code with Git, CMake and MinGW64.
The file organization:
D:.
├───.vscode
├───build
│ ├───.cmake
│ │ └───api
│ │ └───v1
│ │ ├───query
│ │ │ └───client-vscode
│ │ └───reply
│ ├───bin(.dll and .exe file)
│ ├───CMakeFiles
│ │ ├───3.19.2
│ │ │ ├───CompilerIdC
│ │ │ │ └───tmp
│ │ │ └───CompilerIdCXX
│ │ │ └───tmp
│ │ ├───CMakeTmp
│ │ ├───Graph_Algorithm.dir
│ │ │ └───src
│ │ └───Main.dir
│ └───Testing
│ ├───20210421-1414
│ └───Temporary
├───include(.hpp file)
├───rsrc(Including .txt file)
└───src
(Main.cpp, CMakeLists.txt etc)
Details
UGraph
is a class template. I use a char
array to initialize the vertex vector Vertex
and a Edge.txt
to initialize the adjacency matrix Edge
. The Edge.txt
was written in this format:
0 1 1
0 1 2
0 2 3
2 1 3
1 2 1
4 1 1
Vertex1-Weight-Vertex2.
The constructor:
template<typename Tp>
UGraph<Tp>::UGraph(const Tp arr[], size_t num, std::ifstream& edge, Mode mode) : Vertex(arr, arr + num), size(num)
{
// Allocate memory
Edge = new double*[MAX];
for (size_t i = 0; i < MAX; i++){
Edge[i] = new double[10];
for (size_t j = 0; j < MAX; j++){
if(i == j)
Edge[i][j] = 0;
else
Edge[i][j] = Infinity;
}
}
// TODO Get edge data and connect the vertecies
if (!edge || edge.eof()){
throw "Initial file is invalid.";
}
while(!edge.eof()){
double weight;
size_t i, j;// Vertecies indecies
edge >> i;
edge >> weight;
edge >> j;
// Watch
cout << i << ' ' << weight << ' ' << j << endl;
if (i > size - 1 || j > size - 1) { throw "Index overflow at constructor."; }
switch (mode)
{
case Mode::UN_DIRECTED:
Edge[j][i] = weight;
case Mode::DIRECTED:
Edge[i][j] = weight;
default:
break;
}
}
edge.close();
// //Test
// for (size_t i = 0; i < size; i++){
// for (size_t j = 0; j < size; j++){
// if(Edge[i][j] != Infinity){
// cout << Edge[i][j] << ' ';
// }else{
// cout << "INF" << ' ';
// }
// }
// cout << endl;
// }
}
The CMakeLists.txt
:
cmake_minimum_required(VERSION 3.1.0)
project(Graph_Algorithm)
# Collect file
aux_source_directory(./src SRC)
include_directories(./include)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
# Generate lib
add_library(Graph_Algorithm SHARED ${SRC} ${PROJECT_SOURCE_DIR}/include/UGraph.hpp)
# Header file
target_include_directories(Graph_Algorithm
PUBLIC
./include)
# Compile
add_executable(Main main.cpp)
# Link
target_link_libraries(Main Graph_Algorithm)
The Main.cpp:
#include "UGraph.hpp"
int main(){
try{
std::ifstream file("./../../rsrc/DAG.txt");
char s[]{"ABCDEFGHIJKMLNOPQRSTU"};
UGraph<char> ug(s, 14, file, UGraph<char>::Mode::DIRECTED);
std::vector<size_t> vec;
ug.BreadthFirstTraverse(0);
// ug.DepthFirstTraverse();
ug.Prim();
cout << endl;
ug.Kruskal();
ug.Dijstra(3, vec);
}
catch(const std::exception& e){
std::cerr << e.what() << '\n';
}
catch(const char* msg){
std::cerr << "ErrorFound: " << msg << std::endl;
}
return 0;
}
The class UGraph
:
const double Infinity{99999.9};
template<typename Tp>
class UGraph
{
private:
std::vector<Tp> Vertex;
// Adjacent Matrix, Row is out, Colum is in.
double ** Edge;
size_t size;
public:
static const unsigned int MAX{10};
enum class Mode { DIRECTED, UN_DIRECTED };
UGraph();
UGraph(const Tp arr[], size_t num, std::ifstream& edge, Mode mode = Mode::UN_DIRECTED);
~UGraph();
double*& operator[](size_t i) {
if (i > size - 1){
throw "Index Overflow at [] operator.";
}
return Edge[i];
}
auto BreadthFirstTraverse(size_t root);
void DepthFirstTraverse();
void DFS(size_t root, std::vector<bool>& Visited);
void Prim();
void Kruskal();
void Dijstra(size_t v1, std::vector<size_t>& shortestWay);
// void Floyd();
};
Exceptions
If using CMake Launch, it reads some of lines then aborts, shows nothing;
if using cmd or powershell launch, it shows "Initial file is invaild.";
if using gdb, it shows the same massage as powershell.
- This program once worked smoothly. The exceptions happened when another initial file was used.
All the message are contained in exception objects (Most of them are strings), which will be catched by
int main()
them be showed in stderr.