Skip to content

Commit 4ad0080

Browse files
committed
update graph class (code simplify and beautify)
1 parent 050874c commit 4ad0080

File tree

7 files changed

+263
-285
lines changed

7 files changed

+263
-285
lines changed

lib/src/graph.hpp

Lines changed: 49 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ class Graph {
100100
std::vector<Edge> edges{};
101101
edges.reserve(edges_pairs.size());
102102

103-
for (const auto& edge : edges_pairs)
104-
edges.push_back(Edge(edge.first, edge.second));
103+
for (const auto& edge : edges_pairs) edges.push_back(edge);
105104

106105
return Graph(edges);
107106
}
@@ -129,8 +128,7 @@ class Graph {
129128
"match.");
130129

131130
for (size_t i = 0; i < weights.size(); i++)
132-
edges.push_back(
133-
Edge(edges_pairs[i].first, edges_pairs[i].second, weights[i]));
131+
edges.push_back(Edge(edges_pairs[i], weights[i]));
134132

135133
return Graph(edges);
136134
}
@@ -294,13 +292,7 @@ class Graph {
294292
}
295293

296294
/// @brief Проверяет, взвешен ли граф
297-
bool IsWeighted() const {
298-
if (edges_.empty()) return false;
299-
300-
bool is_weighted = true;
301-
for (const auto& edge : edges_) is_weighted &= edge.IsWeighted();
302-
return is_weighted;
303-
}
295+
bool IsWeighted() const { return is_weighted_; }
304296

305297
/// @return `size_t`: кол-во вершин
306298
size_t VertsAmount() const { return verts_.size(); }
@@ -367,11 +359,8 @@ class Graph {
367359
return os;
368360
}
369361

370-
/**
371-
* @brief Делает граф ненаправленным (удаляет лишние ребра)
372-
* @param remove_duplicates: удалять ли дубликаты
373-
*/
374-
void MakeUndirected(bool remove_duplicates = false) {
362+
/// @brief Делает граф ненаправленным (удаляет лишние ребра)
363+
void MakeUndirected() {
375364
std::unordered_set<size_t> seen_edges;
376365
std::vector<Edge> unique_edges;
377366
unique_edges.reserve(EdgesAmount());
@@ -391,8 +380,6 @@ class Graph {
391380

392381
edges_ = std::move(unique_edges);
393382
is_direct_ = false;
394-
395-
if (remove_duplicates) RemoveDuplicates();
396383
}
397384

398385
/// @brief Делает граф направленным (ничего)
@@ -401,19 +388,6 @@ class Graph {
401388
/// @brief Проверяет, направлен ли граф
402389
bool IsDirected() const { return is_direct_; }
403390

404-
/// @brief Удаляет из графа ребрами с одинаковым вершинами
405-
void RemoveDuplicates() {
406-
std::vector<Edge> unique_edges;
407-
unique_edges.reserve(EdgesAmount());
408-
409-
for (const auto& edge : edges_)
410-
if (!Contains(unique_edges, edge)) unique_edges.push_back(edge);
411-
412-
edges_ = std::move(unique_edges);
413-
414-
if (!IsDirected()) MakeUndirected();
415-
}
416-
417391
/**
418392
* @return `std::vector<std::vector<vert_t>>`: список смежности
419393
* @throw `std::logic_error("GetAdjListWithoutKeys: this method is deleted
@@ -495,8 +469,6 @@ class Graph {
495469
* @return `true`: содержится
496470
* @return `false`: не содержится
497471
* @throw `std::logic_error("ContainsEdge: graph is not weighted.")`
498-
* @throw `std::logic_error("ContainsEdge: weight must be greater than
499-
* zero.")`
500472
*/
501473
bool ContainsEdge(const std::tuple<vert_t, vert_t, weight_t>& edge) const {
502474
if (!IsWeighted())
@@ -560,33 +532,22 @@ class Graph {
560532
if (!Contains(verts_, vert)) verts_.push_back(vert);
561533
}
562534

563-
/// @throw `std::invalid_argument(std::string("AddEdge: ") + ex.what())`
564-
void AddEdge(vert_t start_vert, vert_t end_vert, weight_t weight) {
565-
AddVert(start_vert);
566-
AddVert(end_vert);
567-
568-
try {
569-
edges_.emplace_back(Edge(start_vert, end_vert, weight));
570-
}
571-
572-
catch (const std::exception& ex) {
573-
throw std::invalid_argument(std::string("AddEdge: ") + ex.what());
574-
}
535+
/// @warning `"AddEdge: weighted graph must consist of weighted edges.`
536+
void AddEdge(const std::tuple<vert_t, vert_t, weight_t>& edge_tuple) {
537+
if (WeightFromTuple(edge_tuple) == 0)
538+
AddEdge({StartVertFromTuple(edge_tuple), EndVertFromTuple(edge_tuple)});
539+
else
540+
AddEdge_(edge_tuple);
575541
}
576542

577-
/**
578-
* @throw `std::logic_error("AddEdge: weighted graph must consist of
579-
* weighted edges.")`
580-
*/
581-
void AddEdge(vert_t start_vert, vert_t end_vert) {
543+
/// @warning `"AddEdge: weighted graph must consist of weighted edges.`
544+
void AddEdge(const std::pair<vert_t, vert_t>& edge_pair) {
582545
if (IsWeighted())
583-
throw std::logic_error(
584-
"AddEdge: weighted graph must consist of weighted edges.");
546+
std::cerr << "Warning! AddEdge: weighted graph should consist of "
547+
"weighted edges."
548+
<< std::endl;
585549

586-
AddVert(start_vert);
587-
AddVert(end_vert);
588-
589-
edges_.emplace_back(Edge(start_vert, end_vert));
550+
AddEdge_(Edge(edge_pair.first, edge_pair.second, static_cast<weight_t>(0)));
590551
}
591552

592553
/// @throw `std::invalid_argument("RemoveVert: there is no such vert:")`
@@ -622,8 +583,7 @@ class Graph {
622583

623584
edges_.erase(std::remove_if(edges_.begin(), edges_.end(),
624585
[&edge_pair, this](const Edge& e) {
625-
return (Edge(e.StartVert(), e.EndVert()) ==
626-
Edge(edge_pair)) ||
586+
return (e == Edge(edge_pair)) ||
627587
(!IsDirected() &&
628588
Edge(e.EndVert(), e.StartVert()) ==
629589
Edge(edge_pair));
@@ -656,16 +616,21 @@ class Graph {
656616
public:
657617
Edge() = delete;
658618

659-
Edge(vert_t start_vert, vert_t end_vert)
619+
Edge(const vert_t start_vert, const vert_t& end_vert)
660620
: start_vert_{start_vert}, end_vert_{end_vert} {}
661621

662-
Edge(vert_t start_vert, vert_t end_vert, weight_t weight)
622+
Edge(const vert_t& start_vert, vert_t end_vert, weight_t weight)
663623
: start_vert_{start_vert}, end_vert_{end_vert}, weight_{weight} {}
664624

665-
Edge(std::pair<vert_t, vert_t> edge_pair)
625+
Edge(const std::pair<vert_t, vert_t>& edge_pair)
666626
: start_vert_{edge_pair.first}, end_vert_{edge_pair.second} {}
667627

668-
Edge(std::tuple<vert_t, vert_t, weight_t> edge_tuple)
628+
Edge(const std::pair<vert_t, vert_t>& edge_pair, weight_t weight)
629+
: start_vert_{edge_pair.first},
630+
end_vert_{edge_pair.second},
631+
weight_{weight} {}
632+
633+
Edge(const std::tuple<vert_t, vert_t, weight_t>& edge_tuple)
669634
: start_vert_{StartVertFromTuple(edge_tuple)},
670635
end_vert_{EndVertFromTuple(edge_tuple)},
671636
weight_{WeightFromTuple(edge_tuple)} {}
@@ -679,11 +644,13 @@ class Graph {
679644

680645
void SetWeight(weight_t new_weight) { weight_ = new_weight; }
681646

682-
// friend Graph;
683-
684647
bool operator==(const Edge& rhs) const {
685-
return start_vert_ == rhs.start_vert_ && end_vert_ == rhs.end_vert_ &&
686-
weight_ == rhs.weight_;
648+
if (StartVert() != rhs.StartVert() || EndVert() != rhs.EndVert())
649+
return false;
650+
651+
if (IsWeighted() && rhs.IsWeighted()) return Weight() == rhs.Weight();
652+
653+
return true;
687654
}
688655

689656
bool operator!=(const Edge& rhs) const { return !(*this == rhs); }
@@ -727,6 +694,7 @@ class Graph {
727694
std::vector<vert_t> verts_;
728695

729696
bool is_direct_ = true;
697+
bool is_weighted_ = false;
730698

731699
public:
732700
friend std::ostream& operator<<(std::ostream& os,
@@ -736,9 +704,14 @@ class Graph {
736704
}
737705

738706
private:
739-
Graph(const std::vector<Edge>& edges) : edges_{edges}, verts_() {
707+
Graph(const std::vector<Edge>& edges) {
740708
if (edges.empty()) return;
741709

710+
for (const auto& edge : edges) {
711+
if (edge.IsWeighted()) is_weighted_ = true;
712+
AddEdge_(edge);
713+
}
714+
742715
if constexpr (std::is_integral_v<vert_t>) {
743716
// кол-во вершин = максимальная вершина среди ребер, т.е. в этом случае
744717
// происходит заполнение вершин до наибольшей из них в списке ребер
@@ -752,17 +725,23 @@ class Graph {
752725
verts_.resize(max_vert + 1);
753726
std::iota(verts_.begin(), verts_.end(), 0);
754727

755-
} else if constexpr (std::is_same_v<vert_t, std::string>) {
728+
} else if constexpr (std::is_same_v<vert_t, std::string>)
756729
for (const auto& edge : edges_) {
757730
if (!Contains(Verts(), edge.StartVert()))
758731
verts_.push_back(edge.StartVert());
759732

760733
if (!Contains(Verts(), edge.EndVert()))
761734
verts_.push_back(edge.EndVert());
762735
}
763-
}
736+
}
737+
738+
void AddEdge_(const Edge& edge) {
739+
AddVert(edge.StartVert());
740+
AddVert(edge.EndVert());
741+
742+
if (!Contains(edges_, edge)) edges_.emplace_back(edge);
764743

765-
if (!IsDirected()) MakeUndirected();
744+
if (edge.Weight() != 0) is_weighted_ = true;
766745
}
767746

768747
static std::pair<vert_t, vert_t> ParseEdgeString_(

lib/src/utils.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ inline std::istream& operator>>(std::istream& is, std::vector<Type>& vec) {
174174
* @return false: элемент не найден
175175
*/
176176
template <typename T>
177-
bool Contains(const std::vector<T>& vec, const T& value) {
178-
auto it = std::find(vec.begin(), vec.end(), value);
179-
return it != vec.end();
177+
inline bool Contains(const std::vector<T>& vec, const T& value) {
178+
return std::find(vec.begin(), vec.end(), value) != vec.end();
180179
}

0 commit comments

Comments
 (0)