AlgoPlus v0.1.0
Loading...
Searching...
No Matches
rope.h
1#ifndef ROPE_H
2#define ROPE_H
3
4#ifdef TREE_VISUALIZATION_H
5#include "../../visualization/tree_visual/tree_visualization.h"
6#endif
7
8#ifdef __cplusplus
9#include <cassert>
10#include <functional>
11#include <iostream>
12#include <memory>
13#include <queue>
14#include <unordered_map>
15#include <vector>
16#endif
17
31class rope {
32 struct node {
33 int64_t len;
34 bool is_leaf;
35 std::shared_ptr<node> left;
36 std::shared_ptr<node> right;
37 std::string data;
38
39 explicit node(int64_t len, std::shared_ptr<node> left, std::shared_ptr<node> right) {
40 this->len = len;
41 this->is_leaf = false;
42 this->left = left;
43 this->right = right;
44 }
45
46 explicit node(std::string s) {
47 this->len = s.size();
48 this->is_leaf = true;
49 this->left = nullptr;
50 this->right = nullptr;
51 this->data = s;
52 }
53 };
54
55 void _inorder(std::function<void(std::shared_ptr<node>)> callback, std::shared_ptr<node> root) {
56 if (root) {
57 _inorder(callback, root->left);
58 callback(root);
59 _inorder(callback, root->right);
60 }
61 }
62
63 std::vector<std::shared_ptr<node>> ropes;
64 std::shared_ptr<node> root;
65 int64_t _height;
66
67 public:
68 explicit rope(std::string s, int64_t splits = 2) : root(nullptr), _height(-1) {
69 this->create(s, splits);
70 }
71
72 void create(std::string s, int64_t splits = 2);
73
74 std::string inorder();
75
76 int64_t height() { return this->_height; }
77
78#ifdef TREE_VISUALIZATION_H
79 void visualize() {
80 std::string _generated = generate_visualization();
81 tree_visualization::visualize(_generated);
82 }
83#endif
84
85 private:
86 std::string generate_visualization() {
87 std::string _generate = _inorder_gen(root);
88 return _generate;
89 }
90
91 std::shared_ptr<node> split_tree(std::shared_ptr<node> root, int64_t& splits) {
92 std::queue<std::shared_ptr<node>> q;
93 q.push(root);
94 while (splits) {
95 q = std::queue<std::shared_ptr<node>>{};
96 q.push(root);
97 int64_t count_height = -1;
98 while (!q.empty()) {
99 int64_t size = q.size();
100 for (int64_t i = 0; i < size; i++) {
101 std::shared_ptr<node> curr = q.front();
102 q.pop();
103 if (splits <= 0) {
104 q = std::queue<std::shared_ptr<node>>{};
105 break;
106 }
107 if (curr->is_leaf == true) {
108 std::string s1 = (curr->data).substr(0, int(curr->len) / 2 + 1);
109 std::string s2 = (curr->data)
110 .substr(int(curr->len) / 2 + 1,
111 int(curr->len) - int(curr->len) / 2);
112 std::shared_ptr<node> split1 = std::make_shared<node>(s1);
113 std::shared_ptr<node> split2 = std::make_shared<node>(s2);
114
115 std::shared_ptr<node> block_node =
116 std::make_shared<node>(curr->len, split1, split2);
117 curr->data.clear();
118 curr->is_leaf = block_node->is_leaf;
119 curr->len = block_node->len;
120 curr->left = block_node->left;
121 curr->right = block_node->right;
122
123 splits--;
124 }
125
126 if (curr->left != nullptr) {
127 q.push(curr->left);
128 }
129 if (curr->right != nullptr) {
130 q.push(curr->right);
131 }
132 }
133 count_height++;
134 _height = std::max(_height, count_height);
135 }
136 }
137 return root;
138 }
139
140 std::string _inorder_gen(std::shared_ptr<node> root) {
141 std::string _s;
142 if (root->left) {
143 if (root->is_leaf) {
144 _s += '"' + std::to_string(root->len) + ',' + root->data + '"';
145 } else {
146 _s += '"' + std::to_string(root->len) + '"';
147 }
148 _s += "->";
149 if (root->left->is_leaf) {
150 _s += '"' + std::to_string(root->left->len) + ',' + root->left->data + '"';
151 } else {
152 _s += '"' + std::to_string(root->left->len) + '"';
153 }
154 _s += "\n";
155 _s += _inorder_gen(root->left);
156 }
157 if (root->right) {
158 if (root->is_leaf) {
159 _s += '"' + std::to_string(root->len) + ',' + root->data + '"';
160 } else {
161 _s += '"' + std::to_string(root->len) + '"';
162 }
163 _s += "->";
164 if (root->right->is_leaf) {
165 _s += '"' + std::to_string(root->right->len) + ',' + root->right->data + '"';
166 } else {
167 _s += '"' + std::to_string(root->right->len) + '"';
168 }
169 _s += "\n";
170 _s += _inorder_gen(root->right);
171 }
172 return _s;
173 }
174};
175
176void rope::create(std::string s, int64_t splits) {
177 assert(s.size() >= splits);
178
179 std::string s1 = s.substr(0, (int(s.size()) / 2) + 1);
180 std::string s2 = s.substr(int(s.size()) / 2 + 1, int(s.size()) - int(s.size() / 2));
181 std::shared_ptr<node> split1 = std::make_shared<node>(s1);
182 std::shared_ptr<node> split2 = std::make_shared<node>(s2);
183
184 std::shared_ptr<node> root_block = std::make_shared<node>(s.size(), split1, split2);
185 root = root_block;
186 splits--;
187 root = split_tree(root, splits);
188}
189
190std::string rope::inorder() {
191 std::string path;
192 _inorder(
193 [&](std::shared_ptr<node> callbacked) {
194 if (callbacked->is_leaf == true) {
195 path += callbacked->data;
196 }
197 },
198 root);
199 return path;
200}
201
202#endif