I have found this example: Insert nodes in expression trees and have made some minor modifications:
class Node {
public:
std::string data;
Node* left, * right;
Node* parent; // operator
Node(std::string d, Node* p) : data(d), left(NULL), right(NULL), parent(p) {}
};
class ExpressionTree {
public:
Node* root;
int tsize;
ExpressionTree() : root(NULL), tsize(0) {}
void insert(string s);
bool isOperator(string value);
};
bool ExpressionTree::isOperator(string value) {
if (value == "+" || value == "-" ||
value == "*" || value == "/" ||
value == "==")
return true;
return false;
}
void ExpressionTree::insert(std::string s) {
if (root == NULL) {
root = new Node(s, NULL);
++tsize;
}
else {
Node* current = root;
while (true) {
if (isOperator(current->data)) {
if (current->left == NULL) {
current->left = new Node(s, current);
++tsize;
return;
}
else if (current->right == NULL) {
current->right = new Node(s, current);
//++tsize;
return;
}
else {
if (isOperator(current->left->data)) {
current = current->left;
continue;
}
else if (isOperator(current->right->data)) {
current = current->right;
continue;
}
else {
if (current->parent) {
current = current->parent->right;
continue;
}
else {
//std::cout << "Error: only nodes who hold operators "
// << "can have children." << std::endl;
return;
}
}
}
}
else {
//std::cout << "Error: only nodes who hold operators "
// << "can have children." << std::endl;
return;
}
}
}
}
void inorder(Node* node) {
if (node) {
if (node->left && node->parent)
cout << "(";
inorder(node->left);
cout << node->data;
inorder(node->right);
if (node->right && node->parent)
cout << ")";
}
}
What I need is to create random expression tree with limited depth based on input vectors
int maxDepth = 2;
vector<string> operands = { "A", "B", "C" };
vector<string> operators = { "+", "*", "-" };
It would be great if something like this could be implemented:
ExpressionTree expression = generateRandomTree(operands, operators, maxDepth);
Possible inorder solutions in this case are A
, B
, C
(tree depth = 1) or A + B
, A - A
, C - A
etc. if tree depth > 1.
As in the previous link, to make a valid expression a following rules must be applied:
- Each node has zero, one or two children.
- Only nodes containing operators can have children.
- All leaf nodes must be operands.
Method insert
does a good job, but I simply don't know how to generate a random expression tree based on this code.. I appreciate your help in resolving this problem.
Edit: Think out loud, I should probably just repeat executing insert
with random operand or random operator (50-50% chance) until all leaf nodes become operands or maximum depth is reached. Also, I would need to force only random operands for the maxDepth
tree level (if it is reached). Still, implementation is the problem I have..