u01: Add recursive print with cycle detection
This commit is contained in:
parent
08dc634ebb
commit
1f56b00800
|
@ -7,6 +7,14 @@ int main(int argc, char **argv) {
|
||||||
std::cout << *t;
|
std::cout << *t;
|
||||||
delete t;
|
delete t;
|
||||||
t = nullptr;
|
t = nullptr;
|
||||||
|
|
||||||
|
node *n = new node("foo");
|
||||||
|
n->add_child(new node("bar"));
|
||||||
|
n->get_child(0)->add_child(n);
|
||||||
|
std::cout << n->print_recursive();
|
||||||
|
delete n;
|
||||||
|
n = nullptr;
|
||||||
|
|
||||||
node *root = new node("root");
|
node *root = new node("root");
|
||||||
root->add_child(new node("left child"));
|
root->add_child(new node("left child"));
|
||||||
root->add_child(new node("right child"));
|
root->add_child(new node("right child"));
|
||||||
|
|
18
u01/node.cpp
18
u01/node.cpp
|
@ -42,6 +42,24 @@ void node::print(std::ostream &str, std::size_t depth) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string node::print_recursive(std::size_t depth,
|
||||||
|
std::set<const node *> visited) const {
|
||||||
|
std::stringstream output;
|
||||||
|
output << std::string(depth, '\t') << get_name();
|
||||||
|
visited.insert(this);
|
||||||
|
for (const node *child : children) {
|
||||||
|
// std::set::contains is only implemented in C++20
|
||||||
|
if (visited.find(child) == visited.end()) {
|
||||||
|
output << std::endl << child->print_recursive(depth + 1, visited);
|
||||||
|
} else {
|
||||||
|
output << " [↝ " << child->get_name() << "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (depth == 0)
|
||||||
|
output << std::endl;
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &os, node &n) {
|
std::ostream &operator<<(std::ostream &os, node &n) {
|
||||||
n.print(os);
|
n.print(os);
|
||||||
return os;
|
return os;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -14,6 +15,8 @@ public:
|
||||||
node *get_child(std::size_t i) const;
|
node *get_child(std::size_t i) const;
|
||||||
void add_child(node *child);
|
void add_child(node *child);
|
||||||
void print(std::ostream &str, std::size_t depth = 0) const;
|
void print(std::ostream &str, std::size_t depth = 0) const;
|
||||||
|
std::string print_recursive(std::size_t depth = 0,
|
||||||
|
std::set<const node *> visited = {}) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
|
@ -150,3 +150,16 @@ TEST_CASE("Print stream overload") {
|
||||||
|
|
||||||
REQUIRE(output1.str() == output2.str());
|
REQUIRE(output1.str() == output2.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Cycle detection") {
|
||||||
|
node *n = new node("foo");
|
||||||
|
n->add_child(new node("bar"));
|
||||||
|
n->get_child(0)->add_child(n);
|
||||||
|
|
||||||
|
std::stringstream output;
|
||||||
|
output << n->print_recursive();
|
||||||
|
|
||||||
|
REQUIRE(output.str() == "foo\n\tbar [↝ foo]\n");
|
||||||
|
|
||||||
|
delete n;
|
||||||
|
}
|
||||||
|
|
Reference in a new issue