3.2 solved
This commit is contained in:
parent
95ee5f84d1
commit
a8af581125
|
|
@ -0,0 +1,51 @@
|
||||||
|
|
||||||
|
# Name of the binary for Development
|
||||||
|
BINARY = main
|
||||||
|
# Name of the binary for Release
|
||||||
|
FINAL = prototyp
|
||||||
|
# Object files
|
||||||
|
OBJS = extendedgraph2.o main.o
|
||||||
|
# Compiler flags
|
||||||
|
CFLAGS = -Werror -Wall -std=c++17 -fsanitize=address,undefined -g
|
||||||
|
# Linker flags
|
||||||
|
LFLAGS = -fsanitize=address,undefined
|
||||||
|
#Which Compiler to use
|
||||||
|
COMPILER = c++
|
||||||
|
|
||||||
|
|
||||||
|
# all target: builds all important targets
|
||||||
|
all: binary
|
||||||
|
|
||||||
|
final : ${OBJS}
|
||||||
|
${COMPILER} ${LFLAGS} -o ${FINAL} ${OBJS}
|
||||||
|
|
||||||
|
binary : ${OBJS}
|
||||||
|
${COMPILER} ${LFLAGS} -o ${BINARY} ${OBJS}
|
||||||
|
|
||||||
|
# Links the binary
|
||||||
|
${BINARY} : ${OBJS}
|
||||||
|
${COMPILER} ${LFLAGS} -o ${BINARY} ${OBJS}
|
||||||
|
|
||||||
|
|
||||||
|
# Compiles a source-file (any file with file extension .c) into an object-file
|
||||||
|
#
|
||||||
|
# "%" is a wildcard which matches every file-name (similar to * in regular expressions)
|
||||||
|
# Such a rule is called a pattern rule (because it matches a pattern, see https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html),
|
||||||
|
# which are a form of so called implicit rules (see https://www.gnu.org/software/make/manual/html_node/Implicit-Rules.html)
|
||||||
|
# "$@" and "$<" are so called automatic variables (see https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html)
|
||||||
|
%.o : %.cpp
|
||||||
|
${COMPILER} -c ${CFLAGS} -o $@ $<
|
||||||
|
|
||||||
|
|
||||||
|
# Rules can not only be used for compiling a program but also for executing a program
|
||||||
|
run: ${BINARY}
|
||||||
|
./${BINARY}
|
||||||
|
|
||||||
|
|
||||||
|
# Delete all build artifacts
|
||||||
|
clean :
|
||||||
|
rm -rf ${BINARY} ${OBJS}
|
||||||
|
|
||||||
|
|
||||||
|
# all and clean are a "phony" targets, meaning they are no files
|
||||||
|
.PHONY : all clean
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* -- Struct Edge -- */
|
||||||
|
class Edge {
|
||||||
|
private:
|
||||||
|
std::string m_src; // string source; beginning of the directed connection
|
||||||
|
std::string m_dest; // string destination; end of the directed connection
|
||||||
|
int m_weight; // weight
|
||||||
|
public:
|
||||||
|
Edge(std::string src, std::string dest, int weight)
|
||||||
|
: m_src(src), m_dest(dest), m_weight(weight){};
|
||||||
|
const int &getWeight() const { return this->m_weight; };
|
||||||
|
void setWeight(int weight) { this->m_weight = weight; };
|
||||||
|
const std::string &getSrc() const { return this->m_src; };
|
||||||
|
void setSrc(std::string src) { this->m_src = src; };
|
||||||
|
const std::string &getDest() const { return this->m_dest; };
|
||||||
|
void setDest(std::string dest) { this->m_dest = dest; };
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,243 @@
|
||||||
|
#include "extendedgraph2.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
ExtendedGraph::ExtendedGraph() { // Default Constructor
|
||||||
|
this->vertices =
|
||||||
|
std::vector<std::string>(0); // Empty Vector for this->vertices
|
||||||
|
this->adjacencyMatrix.resize(
|
||||||
|
0, std::vector<int>(0)); // 0x0 Matrix for this->adjacencyMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --
|
||||||
|
Constructor with params
|
||||||
|
-- */
|
||||||
|
ExtendedGraph::ExtendedGraph(const std::vector<std::string> &vertices,
|
||||||
|
const std::vector<Edge> &edges) {
|
||||||
|
this->vertices = vertices; // definition of this->vertex through parameter
|
||||||
|
// vertices (type: std::vector<std::string>)
|
||||||
|
this->adjacencyMatrix.resize(
|
||||||
|
vertices.size(),
|
||||||
|
std::vector<int>(
|
||||||
|
this->vertices.size())); // creation of an NxN Matrix, based on the
|
||||||
|
// size of vertices
|
||||||
|
|
||||||
|
for (int i = 0; i < edges.size(); i++) {
|
||||||
|
insertEdge(edges[i]); // edges are added one by one, utilizing the
|
||||||
|
// insertEdge()-Function
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- /
|
||||||
|
Function to insert a vertex into the Graph;
|
||||||
|
- takes one argument of type std::string that represents a vertex
|
||||||
|
- returns void
|
||||||
|
/ -- */
|
||||||
|
void ExtendedGraph::insertVertex(const std::string &vertex) {
|
||||||
|
if (this->resolveVertex(vertex) != -1) { /* -- */
|
||||||
|
std::cerr
|
||||||
|
<< "Vertex already in Graph!\n"; /* Calls this->resolveVertex to check
|
||||||
|
if a given vertex is already in the
|
||||||
|
Graph. Returns with an error, if
|
||||||
|
this is the case. */
|
||||||
|
return; /* -- */
|
||||||
|
}
|
||||||
|
this->vertices.push_back(vertex); // adds a vertetx via the push_back
|
||||||
|
// function provided by std::vector
|
||||||
|
this->adjacencyMatrix.resize(
|
||||||
|
this->vertices.size(),
|
||||||
|
std::vector<int>(this->vertices.size())); // resizes the adjacencyMatrix
|
||||||
|
// to the new size
|
||||||
|
for (int i = 0; i < this->vertices.size(); i++) { /* -- */
|
||||||
|
adjacencyMatrix[i].resize(
|
||||||
|
this->vertices.size()); /* resizes every "sub" vector of the matrix to
|
||||||
|
the new size */
|
||||||
|
} /* -- */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- /
|
||||||
|
Function to delete a vertex from the Graph;
|
||||||
|
- takes one argument of type std::string that represents a vertex
|
||||||
|
- returns void
|
||||||
|
/ -- */
|
||||||
|
void ExtendedGraph::deleteVertex(const std::string &vertex) {
|
||||||
|
int index = this->resolveVertex(vertex);
|
||||||
|
if (index == -1) { /* -- */
|
||||||
|
std::cerr << "Vertex not found\n"; /* Calls this->resolveVertex to check if
|
||||||
|
a given vertex is already in the
|
||||||
|
Graph. Returns with an error, if this
|
||||||
|
is the case. */
|
||||||
|
return; /* -- */
|
||||||
|
}
|
||||||
|
this->vertices.erase(
|
||||||
|
this->vertices.begin() +
|
||||||
|
index); // erases the vertex at position "index" from this->vertices
|
||||||
|
|
||||||
|
this->adjacencyMatrix.erase(
|
||||||
|
this->adjacencyMatrix.begin() +
|
||||||
|
index); // erases the entries from the adjacencyMatrix at "column"
|
||||||
|
// position "index"
|
||||||
|
for (int i = 0; i < this->adjacencyMatrix[0].size(); i++) { /* -- */
|
||||||
|
this->adjacencyMatrix[i].erase(this->adjacencyMatrix[i].begin() +
|
||||||
|
index); /* erases the entries from the
|
||||||
|
adjacencyMatrix in every "row" */
|
||||||
|
} /* -- */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- /
|
||||||
|
Function to insert an Edge
|
||||||
|
- takes one argument of type Edge that represents an edge
|
||||||
|
- returns void
|
||||||
|
/ -- */
|
||||||
|
void ExtendedGraph::insertEdge(const Edge &edge) {
|
||||||
|
int col = this->resolveVertex(
|
||||||
|
edge.getSrc()); // resolves the src of the edge to the index within the
|
||||||
|
// adjacencyMatrix
|
||||||
|
int row = this->resolveVertex(
|
||||||
|
edge.getDest()); // resolves the dest of the edge to the index within the
|
||||||
|
// adjacencyMatrix
|
||||||
|
if (col == -1 || row == -1) { /* -- */
|
||||||
|
std::cerr << "Vertex not found!\n"; /* Calls this->resolveVertex to check
|
||||||
|
if a given vertex is already in the
|
||||||
|
Graph. Returns with an error, if this
|
||||||
|
is the case. */
|
||||||
|
return; /* -- */
|
||||||
|
}
|
||||||
|
|
||||||
|
this->adjacencyMatrix[col][row] =
|
||||||
|
edge.getWeight(); // sets the value of the adjacencyMatrix at position
|
||||||
|
// [col][row] to the weight of the edge
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- /
|
||||||
|
Function to delete an Edge
|
||||||
|
- takes one argument of type Edge that represents an edge
|
||||||
|
- returns void
|
||||||
|
/ -- */
|
||||||
|
void ExtendedGraph::deleteEdge(const Edge &edge) {
|
||||||
|
int col = this->resolveVertex(
|
||||||
|
edge.getSrc()); // resolves the src of the edge to the index within the
|
||||||
|
// adjacencyMatrix
|
||||||
|
int row = this->resolveVertex(
|
||||||
|
edge.getDest()); // resolves the dest of the edge to the index within the
|
||||||
|
// adjacencyMatrix
|
||||||
|
if (col == -1 || row == -1) { /* -- */
|
||||||
|
std::cerr << "Vertex not found!\n"; /* Calls this->resolveVertex to check
|
||||||
|
if a given vertex is already in the
|
||||||
|
Graph. Returns with an error, if this
|
||||||
|
is the case. */
|
||||||
|
return; /* -- */
|
||||||
|
}
|
||||||
|
this->adjacencyMatrix[col][row] =
|
||||||
|
0; // sets the value of the adjacencyMatrix at position [col][row] to 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- /
|
||||||
|
Function to check whether vertex v2 is adjacent to vertex v1
|
||||||
|
- takes one argument of type Edge that represents an edge
|
||||||
|
- returns void
|
||||||
|
/ -- */
|
||||||
|
bool ExtendedGraph::adjacent(const std::string &vertex1,
|
||||||
|
const std::string &vertex2) {
|
||||||
|
int indexVertex1 = this->resolveVertex(vertex1);
|
||||||
|
int indexVertex2 = this->resolveVertex(vertex2);
|
||||||
|
if (indexVertex1 == -1 || indexVertex2 == -1) {
|
||||||
|
std::cerr << "Vertex not found!\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// As adjacency is an equivalency relation, we need to check for a possible
|
||||||
|
// relation in both direction. This can be achieved by swapping the the
|
||||||
|
// position specifications of the adjacencyMatrix (from
|
||||||
|
// [indexVertex1][indexVertex2] to [indexVertex2][indexVertex1]).
|
||||||
|
if (this->adjacencyMatrix[indexVertex1][indexVertex2] != 0 ||
|
||||||
|
this->adjacencyMatrix[indexVertex2][indexVertex1] != 0) {
|
||||||
|
return true; // if a connection (in any direction) is found, return true
|
||||||
|
} else {
|
||||||
|
return false; // else, return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- /
|
||||||
|
Function that returns an std::vector of std::string representing the
|
||||||
|
neighbouring vertices of the parameter std::string vertex. Other than adjacent,
|
||||||
|
neighbourhood is a directed relationship, which means that a vertex "A" can be
|
||||||
|
the neighbour of "B", but this does not automatically imply that "B" is the
|
||||||
|
neighbour of "A".
|
||||||
|
- takes one argument of type std::string that represents a vertex
|
||||||
|
- returns a std::vector of std::string
|
||||||
|
/ -- */
|
||||||
|
std::vector<std::string> ExtendedGraph::neighbours(const std::string &vertex) {
|
||||||
|
int indexVertex = this->resolveVertex(
|
||||||
|
vertex); // resolves the vertex to the index within the adjacencyMatrix
|
||||||
|
std::vector<std::string> resVector =
|
||||||
|
{}; // initializes an empty std::vetor of std::string
|
||||||
|
for (int i = 0; i < this->adjacencyMatrix[indexVertex].size();
|
||||||
|
i++) { /* Loops through all entries of the subvector of
|
||||||
|
adjacencyMatrix[indexVertex] */
|
||||||
|
if (this->adjacencyMatrix[indexVertex][i] !=
|
||||||
|
0) { /* and checks if the entry at position [indexVertex][i] is not 0.
|
||||||
|
*/
|
||||||
|
resVector.push_back(
|
||||||
|
this->vertices[i]); /* If the condition is fulfilled, add the vertex
|
||||||
|
(name) to the result vector resVector */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resVector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- /
|
||||||
|
Function that prints the current Graph's adjacencyMatrix.
|
||||||
|
- prints the Graph by utilizing std::cout
|
||||||
|
- returns void
|
||||||
|
/ -- */
|
||||||
|
void ExtendedGraph::printGraph() {
|
||||||
|
std::cout << "--------------------------------------------\n";
|
||||||
|
std::cout << "\t\t\t";
|
||||||
|
for (int i = 0; i < this->vertices.size(); i++) {
|
||||||
|
std::cout << this->vertices[i] << "\t";
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
for (int i = 0; i < this->vertices.size(); i++) {
|
||||||
|
std::cout << " " << this->vertices[i] << "\t\t-->\t";
|
||||||
|
for (int j = 0; j < this->vertices.size(); j++) {
|
||||||
|
std::cout << this->adjacencyMatrix[i][j] << "\t";
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
std::cout << "--------------------------------------------\n";
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -- /
|
||||||
|
Function that resolves a parameter std::string name and returns it's index
|
||||||
|
within the this->vertices vector; between vertices of type std::string and the
|
||||||
|
corresponding index (in the adjacencyMatrix) of type int.
|
||||||
|
- takes one argument of type std::string that represents a vertex
|
||||||
|
- returns an int representing the vertex's index in the adjacencyMatrix;
|
||||||
|
- function returns -1 in case the resolution of the name is unsuccessful
|
||||||
|
/ -- */
|
||||||
|
int ExtendedGraph::resolveVertex(const std::string &vertexName) {
|
||||||
|
for (int i = 0; i < this->vertices.size(); i++) {
|
||||||
|
if (this->vertices[i] == vertexName) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtendedGraph::depthFirstSearch(std::string vertex) {
|
||||||
|
std::vector<bool> visited;
|
||||||
|
visited.resize(this->vertices.size(), false);
|
||||||
|
this->doTheDFS(vertex, visited);
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtendedGraph::doTheDFS(std::string vertex, std::vector<bool> &visited) {
|
||||||
|
std::cout << vertex << std::flush;
|
||||||
|
visited[resolveVertex(vertex)] = true;
|
||||||
|
std::vector<std::string> theneighbours = this->neighbours(vertex);
|
||||||
|
for (int i = 0; i < theneighbours.size(); i++) {
|
||||||
|
if (!visited[resolveVertex(theneighbours[i])]) {
|
||||||
|
std::cout << " --> ";
|
||||||
|
doTheDFS(theneighbours[i], visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
#include <iostream> /* cout, cerr */
|
||||||
|
#include <limits.h> /* INT_MAX */
|
||||||
|
#include <sstream> /* type stringstream to easily concat a result string */
|
||||||
|
#include <string> /* type string */
|
||||||
|
#include <vector> /* type vector */
|
||||||
|
|
||||||
|
#include "edge.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void vectorToString(std::vector<std::string> vector);
|
||||||
|
|
||||||
|
/* -- Class Graph -- */
|
||||||
|
class ExtendedGraph {
|
||||||
|
private:
|
||||||
|
std::vector<std::string> vertices; // vector connecting vertices with
|
||||||
|
// indicies; needed for name resolution
|
||||||
|
|
||||||
|
std::vector<bool> visited = {false};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExtendedGraph(); // default constructor
|
||||||
|
ExtendedGraph(const std::vector<std::string> &vertices,
|
||||||
|
const std::vector<Edge> &edges); // param. constructor
|
||||||
|
std::vector<std::vector<int>>
|
||||||
|
adjacencyMatrix; // vector of vectors containing integers (the adjacency
|
||||||
|
// matrix)
|
||||||
|
|
||||||
|
/* --
|
||||||
|
Resolves a given string of a vertex and returns its position in the
|
||||||
|
adjacencyMatrix (as integer). Returns -1 if name could not be resolved,
|
||||||
|
which indicates the the name was not found.
|
||||||
|
-- */
|
||||||
|
int resolveVertex(const std::string &name);
|
||||||
|
void
|
||||||
|
printGraph(); // prints out the graph with vertices and the adjacencyMatrix
|
||||||
|
|
||||||
|
/* --
|
||||||
|
Graph Manipulation Functions
|
||||||
|
-- */
|
||||||
|
void insertVertex(
|
||||||
|
const std::string &vertex); // inserts a new vertex; throws error, if
|
||||||
|
// vertex already exists in Graph
|
||||||
|
void deleteVertex(
|
||||||
|
const std::string &vertex); // deletes a vertex from the Graph; throws an
|
||||||
|
// error, if vertex does not exist
|
||||||
|
void insertEdge(
|
||||||
|
const Edge &edge); // inserts a new edge; parameter can be {std::string,
|
||||||
|
// std::string} due to implicit cast...
|
||||||
|
// ...does not check if the edge already exists, nor
|
||||||
|
// notifies user/programmer
|
||||||
|
void deleteEdge(
|
||||||
|
const Edge &edge); // deletes an edge; parameter can be {std::string,
|
||||||
|
// std::string} due to implicit cast...
|
||||||
|
// ...does not check if edge exists
|
||||||
|
bool adjacent(const std::string &vertex1,
|
||||||
|
const std::string
|
||||||
|
&vertex2); // checks if vertex1 and vertex2 are adjacent;
|
||||||
|
// returns boolean; adjacency indicates that...
|
||||||
|
// ...a direct connection between a <--> b
|
||||||
|
// (direction NOT important) exists
|
||||||
|
std::vector<std::string>
|
||||||
|
neighbours(const std::string
|
||||||
|
&vertex); // returns a vector of strings, containing all
|
||||||
|
// neighbouring vertices of the parameter vertex...
|
||||||
|
// ...Neighbours are all vertices that a given
|
||||||
|
// vertex is connected to through OUTGOING edges
|
||||||
|
|
||||||
|
void depthFirstSearch(std::string vertex);
|
||||||
|
void doTheDFS(std::string vertex, std::vector<bool> &visited);
|
||||||
|
int getEdgeWeight(std::string sourceVertex, std::string targetVertex);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
|
||||||
|
#include "edge.h"
|
||||||
|
#include "extendedgraph2.h"
|
||||||
|
#include <iostream> /* cout, cerr */
|
||||||
|
#include <sstream> /* type stringstream to easily concat a result string */
|
||||||
|
#include <string> /* type string */
|
||||||
|
#include <vector> /* type vector */
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
/* Creation of Graph */
|
||||||
|
std::vector<std::string> vertices = {
|
||||||
|
"London", "Mailand", "Wien", "Madrid", "Rom",
|
||||||
|
"Paris", "Amsterdam", "Moskau", "Berlin", "Lyon"};
|
||||||
|
std::vector<Edge> edges = {
|
||||||
|
{"London", "Mailand", 2}, {"London", "Wien", 2},
|
||||||
|
{"Mailand", "London", 2}, {"Mailand", "Wien", 6},
|
||||||
|
{"Mailand", "Madrid", 5}, {"Wien", "London", 2},
|
||||||
|
{"Wien", "Mailand", 6}, {"Wien", "Rom", 4},
|
||||||
|
{"Wien", "Paris", 5}, {"Madrid", "Mailand", 5},
|
||||||
|
{"Madrid", "Rom", 5}, {"Madrid", "Lyon", 3},
|
||||||
|
{"Rom", "Wien", 4}, {"Rom", "Madrid", 5},
|
||||||
|
{"Rom", "Moskau", 3}, {"Rom", "Lyon", 4},
|
||||||
|
{"Amsterdam", "Paris", 1}, {"Amsterdam", "Moskau", 1},
|
||||||
|
{"Moskau", "Rom", 3}, {"Moskau", "Paris", 1},
|
||||||
|
{"Moskau", "Amsterdam", 1}, {"Moskau", "Berlin", 2},
|
||||||
|
{"Berlin", "Moskau", 2}, {"Berlin", "Lyon", 2},
|
||||||
|
{"Lyon", "Madrid", 3}, {"Lyon", "Rom", 4},
|
||||||
|
{"Lyon", "Paris", 2}, {"Lyon", "Berlin", 2}};
|
||||||
|
ExtendedGraph g(vertices, edges);
|
||||||
|
g.printGraph();
|
||||||
|
g.depthFirstSearch("London");
|
||||||
|
g.depthFirstSearch("Madrid");
|
||||||
|
|
||||||
|
/* insertVertices */
|
||||||
|
// g.insertVertex("D");
|
||||||
|
// g.insertVertex("H");
|
||||||
|
// g.printGraph();
|
||||||
|
|
||||||
|
/* insertEdges */
|
||||||
|
// g.insertEdge({"C", "D"});
|
||||||
|
// g.insertEdge({"F", "H"});
|
||||||
|
// g.insertEdge({"G", "H"});
|
||||||
|
// g.insertEdge({"D", "H"});
|
||||||
|
// g.printGraph();
|
||||||
|
|
||||||
|
/* deleteEdges */
|
||||||
|
// g.deleteEdge({"D", "H"});
|
||||||
|
// g.printGraph();
|
||||||
|
|
||||||
|
/* Delete Vertices */
|
||||||
|
// g.deleteVertex("C");
|
||||||
|
// g.printGraph();
|
||||||
|
|
||||||
|
/* Adjacency */
|
||||||
|
// std::cout << "Adjacent B --> A? " << g.adjacent("B", "A") << "\n";
|
||||||
|
// std::cout << "Adjacent A --> B? " << g.adjacent("A", "B") << "\n";
|
||||||
|
// std::cout << "Adjacent A --> H? " << g.adjacent("A", "H") << "\n";
|
||||||
|
|
||||||
|
/* Neighbourhood */
|
||||||
|
// std::cout << "\n";
|
||||||
|
// std::cout << "Neighbours of B: ";
|
||||||
|
// vectorToString(g.neighbours("B"));
|
||||||
|
// std::cout << "Neighbours of A: ";
|
||||||
|
// vectorToString(g.neighbours("A"));
|
||||||
|
// std::cout << "Neighbours of H: ";
|
||||||
|
// vectorToString(g.neighbours("H"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void vectorToString(std::vector<std::string> vector) {
|
||||||
|
for (int i = 0; i < vector.size(); i++) {
|
||||||
|
std::cout << vector[i] << "\t";
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue