Sokolmish

ASCII tree printers

Jan 27th, 2021
1,053
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.     Created by Mikhail Sokolovskiy <sokolmish@gmail.com>
  3.     Can be used by anyone for any purpose :)
  4.     Compilation:
  5.     g++ --std=c++11 -o trees trees.cpp
  6. */
  7.  
  8. #include <iostream>
  9. #include <string>
  10. #include <sstream>
  11. #include <vector>
  12. #include <stack>
  13.  
  14. class TreeNode {
  15. private:
  16.     std::string name;
  17.     std::vector<TreeNode*> childs;
  18.  
  19.     void printVertRec(std::stringstream &ss, std::vector<bool> &prev) const {        
  20.         int indent = (int)(prev.size()) - 1;
  21.         if (indent != 0) {
  22.             for (int i = 1; i < indent; i++)
  23.                 ss << (prev[i] ? "  " : "│ ");
  24.             if (prev.back())
  25.                 ss << "└─" << name << std::endl;
  26.             else
  27.                 ss << "├─" << name << std::endl;
  28.         }
  29.         else {
  30.             ss << name << std::endl;
  31.         }
  32.         if (childs.size() != 0) {
  33.             prev.push_back(false);
  34.             for (int i = 0; i < (int)(childs.size()) - 1; i++)
  35.                 childs[i]->printVertRec(ss, prev);
  36.             prev[prev.size() - 1] = true;
  37.             childs[childs.size() - 1]->printVertRec(ss, prev);
  38.             prev.pop_back();
  39.         }
  40.     }
  41.  
  42.     void printHorRec(std::stringstream &ss, std::vector<int> &prev) const {
  43.         if (prev.back() != 0) {
  44.             for (int i = 1; i < (int)(prev.size()) - 1; i++) {
  45.                 for (int j = 0; j < abs(prev[i]); j++)
  46.                     ss << " ";
  47.                 ss << ((prev[i] < 0) ? "  " : "│ ");
  48.             }
  49.            
  50.             for (int j = 0; j < abs(prev.back()); j++)
  51.                 ss << " ";
  52.             ss << ((prev.back() < 0) ? "└─" : "├─");
  53.         }
  54.  
  55.         if (!childs.empty()) {
  56.             std::stack<const TreeNode*> stack;
  57.             stack.push(this);
  58.  
  59.             const TreeNode *cur = stack.top();
  60.             while (!cur->childs.empty()) {
  61.                 ss << cur->name;
  62.                 if (cur->childs.size() == 1) {
  63.                     ss << "───";
  64.                     prev.push_back(-(cur->name.size() + 1));
  65.                 }
  66.                 else {
  67.                     ss << "─┬─";
  68.                     prev.push_back(cur->name.size() + 1);
  69.                 }
  70.  
  71.                 stack.push(cur->childs.front());
  72.                 cur = stack.top();
  73.             }
  74.            
  75.             ss << cur->name << std::endl;
  76.             prev.push_back(0);
  77.  
  78.             while (!stack.empty()) {
  79.                 int childsCount = stack.top()->childs.size();
  80.                 if (childsCount > 1) {
  81.                     for (int i = 1; i < childsCount - 1; i++)
  82.                         stack.top()->childs[i]->printHorRec(ss, prev);
  83.                     prev[prev.size() - 1] *= -1;
  84.                     stack.top()->childs[childsCount - 1]->printHorRec(ss, prev);
  85.                 }
  86.  
  87.                 stack.pop();
  88.                 prev.pop_back();
  89.             }
  90.         }
  91.         else {
  92.             ss << name << std::endl;
  93.         }
  94.     }
  95.  
  96. public:
  97.     explicit TreeNode() = default;
  98.     TreeNode(const std::string &name) : name(name) {}
  99.  
  100.     void setName(const std::string &name) {
  101.         this->name = name;
  102.     }
  103.     void addChild(TreeNode *child) {
  104.         childs.push_back(child);
  105.     }
  106.  
  107.     std::string getName() const {
  108.         return name;
  109.     }
  110.     std::vector<TreeNode*> getChilds() const {
  111.         return childs;
  112.     }
  113.  
  114.     std::string printVert() const {
  115.         std::stringstream ss;
  116.         std::vector<bool> prev;
  117.         prev.push_back(true);
  118.         printVertRec(ss, prev);
  119.         return ss.str();
  120.     }
  121.  
  122.     std::string printHor() const {
  123.         std::stringstream ss;
  124.         std::vector<int> prev;
  125.         prev.push_back(0);
  126.         printHorRec(ss, prev);
  127.         return ss.str();
  128.     }
  129.  
  130.     ~TreeNode() {
  131.         for (auto e : childs)
  132.             delete e;
  133.     }
  134. };
  135.  
  136. TreeNode* createTree() {
  137.     TreeNode *root = new TreeNode("root");
  138.     TreeNode *lang = new TreeNode("lang");
  139.     TreeNode *greek = new TreeNode("greek");
  140.     TreeNode *color = new TreeNode("color");
  141.  
  142.     TreeNode *alpha = new TreeNode("alpha");
  143.     TreeNode *beta = new TreeNode("beta");
  144.     TreeNode *gamma = new TreeNode("gamma");
  145.     TreeNode *delta = new TreeNode("delta");
  146.  
  147.     TreeNode *black = new TreeNode("black");
  148.     TreeNode *white = new TreeNode("white");
  149.     TreeNode *red = new TreeNode("red");
  150.     TreeNode *purple = new TreeNode("purple");
  151.  
  152.     for (int i = 0; i < 3; i++) {
  153.         black->addChild(new TreeNode(std::to_string(i * 1 + 1)));
  154.         beta->addChild(new TreeNode(std::to_string(i * 3 + 10)));
  155.     }
  156.     for (int i = 0; i < 2; i++) {
  157.         white->addChild(new TreeNode(std::to_string(i * 1 + 3)));
  158.         purple->addChild(new TreeNode(std::to_string(i * 2 + 23)));
  159.         delta->addChild(new TreeNode(std::to_string(i * 5 + 102)));
  160.     }
  161.     for (int i = 0; i < 3; i++) {
  162.         red->addChild(new TreeNode(std::to_string(i * 12 + 53)));
  163.         alpha->addChild(new TreeNode(std::to_string(i * 16 + 36)));
  164.         gamma->addChild(new TreeNode(std::to_string(i * 7 + 12)));
  165.     }
  166.     greek->addChild(alpha);
  167.     greek->addChild(beta);
  168.     greek->addChild(gamma);
  169.     greek->addChild(delta);
  170.     color->addChild(black);
  171.     color->addChild(white);
  172.     color->addChild(red);
  173.     color->addChild(purple);
  174.     lang->addChild(greek);
  175.     root->addChild(lang);
  176.     root->addChild(color);
  177.  
  178.     return root;
  179. }
  180.  
  181. int main(int argc, char **argv) {
  182.     TreeNode *root = createTree();
  183.     std::cout << root->printVert() << std::endl;
  184.     std::cout << std::endl;
  185.     std::cout << root->printHor() << std::endl;
  186.     delete root;
  187.     return 0;
  188. }
  189.  
RAW Paste Data