treeify.cpp (1724B)
1 #include <iostream> 2 #include <sstream> 3 #include <iomanip> 4 5 using namespace std; 6 7 constexpr string_view space = " "; 8 constexpr string_view stem = "\u2502"; 9 constexpr string_view leaf = "\u2514"; 10 constexpr string_view branch = "\u251C"; 11 12 13 struct node 14 { 15 string name; 16 node* parent = nullptr; 17 node* next_sibling = nullptr; 18 node* first_child = nullptr; 19 20 node(string name) 21 : name(name) 22 {} 23 24 auto operator <=>(string const& rhs) const 25 { 26 return name <=> rhs; 27 } 28 29 ~node() 30 { 31 if (next_sibling) 32 delete next_sibling; 33 if (first_child) 34 delete first_child; 35 } 36 }; 37 38 static void trunk(ostream& out, node* node) 39 { 40 if (not node or not node->parent) 41 return; 42 trunk(out, node->parent); 43 out << (node->next_sibling ? stem : space); 44 } 45 46 static ostream& operator <<(ostream& out, node* node) 47 { 48 if (not node) 49 return out; 50 51 trunk(out, node->parent); 52 if (node->parent) 53 out << (node->next_sibling ? branch : leaf); 54 if (node->first_child) 55 out << "\e[34;1m"; 56 out << node->name; 57 if (node->first_child) 58 out << "\e[m/"; 59 return out 60 << endl 61 << node->first_child 62 << node->next_sibling; 63 } 64 65 int main() 66 { 67 string line; 68 node* head = nullptr; 69 70 while (getline(cin, line)) 71 { 72 istringstream in{line}; 73 string name; 74 node** current = &head; 75 node* parent = nullptr; 76 77 while (getline(in, name, '/')) 78 { 79 while (*current && (*current)->name < name) 80 current = &(*current)->next_sibling; 81 if (*current && (*current)->name == name) 82 { 83 parent = *current; 84 current = &parent->first_child; 85 continue; 86 } 87 node* nod = new node{name}; 88 nod->next_sibling = *current; 89 nod->parent = parent; 90 *current = parent = nod; 91 current = &nod->first_child; 92 } 93 } 94 95 cout << head; 96 97 if (head) 98 delete head; 99 }