#include <bits/stdc++.h>
#define MAX_SIZE 50
using namespace std;
struct Node{
char data;
struct Node *left;
struct Node *right;
};
class InfixToPrePost{
public:
/** Initialize your data structure here. */
char a[MAX_SIZE];
int top;
InfixToPrePost() {
top = -1;
}
void push(char c){
if(top == MAX_SIZE - 1){
cout<<"Stack is full\n";
return;
}
a[++top] = c;
}
char topElement(){
return a[top];
}
char pop(){
return a[top--];
}
bool isEmpty(){
return top == -1;
}
int priority(char c){
if(c == '(')
return 0;
if(c == '+' || c== '-')
return 1;
if(c == '*' || c == '/' || c == '%')
return 2;
if(c == '^')
return 3;
return 0;
}
string convertToPostfix(string inp){
string ans = "";
for(int i = 0; i < inp.length(); ++i){
if(isalnum(inp[i])){
ans += inp[i];
}
else if(inp[i] == '('){
push('(');
}
else if(inp[i] == ')'){
char t;
while((t = pop()) != '(')
ans += t;
}
else{
while(!isEmpty() && priority(topElement()) >= priority(inp[i])){
ans += pop();
}
push(inp[i]);
}
}
while(!isEmpty()){
ans += pop();
}
return ans;
}
string convertToPrefix(string inp){
int len = inp.length();
for(int i = 0; i < len/2 + 1; ++i){
char t = (inp[i] == '(' ? ')' : (inp[i] == ')' ? '(': inp[i]));
inp[i] = (inp[len-i-1] == '(' ? ')' : (inp[len-i-1] == ')' ? '(': inp[len-i-1]));
inp[len-i-1] = t;
}
inp = convertToPostfix(inp);
reverse(inp.begin(), inp.end());
return inp;
}
};
class ExpressionTree{
public:
struct Node *root;
stack<Node*> st;
ExpressionTree(){
root = NULL;
}
Node *getNode(char val){
Node *newNode = new Node;
newNode->data = val;
newNode->left = newNode->right = NULL;
return newNode;
}
void convertInfixToTree(string str){
InfixToPrePost obj;
str = obj.convertToPostfix(str);
convertPostfixToTree(str);
}
void convertPostfixToTree(string &str){
for(auto &val: str){
if(isalnum(val)){
st.push(getNode(val));
}
else{
Node *newNode = getNode(val);
newNode->right = st.top(); st.pop();
newNode->left = st.top(); st.pop();
st.push(newNode);
}
}
root = st.top(); st.pop();
}
void convertPrefixToTree(string &str){
for(int i = str.size()-1; i > -1; --i){
if(isalnum(str[i])){
st.push(getNode(str[i]));
}
else{
Node *newNode = getNode(str[i]);
newNode->left = st.top(); st.pop();
newNode->right = st.top(); st.pop();
st.push(newNode);
}
}
root = st.top(); st.pop();
}
int evaluateExpression(Node *rt){
if(!rt->left && !rt->right)
return rt->data - '0';
int left = evaluateExpression(rt->left);
int right = evaluateExpression(rt->right);
return op(rt->data, left, right);
}
int op(char &op, int &left, int &right){
if(op == '+')
return left + right;
else if(op == '*')
return left * right;
else if(op == '-')
return left - right;
else if(op == '%')
return left % right;
else if(op == '/')
return left / right;
}
void inOrder(Node *rt){
if(!rt)
return;
inOrder(rt->left);
cout<<rt->data<<" ";
inOrder(rt->right);
}
void postOrder(Node *rt){
if(!rt)
return;
postOrder(rt->left);
postOrder(rt->right);
cout<<rt->data<<" ";
}
void preOrder(Node *rt){
if(!rt)
return;
cout<<rt->data<<" ";
preOrder(rt->left);
preOrder(rt->right);
}
};
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int opt;
string expression;
ExpressionTree etree;
cout<<"Operations available on Expresssion tree are:\n";
cout<<"1. Infix to expression tree\n2. Postfix to expression tree\n3. Prefix to expression tree\n"
"4. InOrder\n5. PreOrder\n6. PostOrder\n7. Evaluate expression\n8. Exit\n";
cout<<"*****************************************************************\n";
while(true){
cin>>opt;
switch(opt){
case 1:
cin>>expression;
cout<<"Converting the infix expression \""
<<expression<<"\" to expression tree.\n";
etree.convertInfixToTree(expression);
break;
case 2:
cin>>expression;
cout<<"Converting the postfix expression \""
<<expression<<"\" to expression tree.\n";
etree.convertPostfixToTree(expression);
break;
case 3:
cin>>expression;
cout<<"Converting the prefix expression \""
<<expression<<"\" to expression tree.\n";
etree.convertPrefixToTree(expression);
break;
case 4:
cout<<"InOrder traversal: ";
etree.inOrder(etree.root); cout<<"\n";
break;
case 5:
cout<<"PreOrder traversal: ";
etree.preOrder(etree.root); cout<<"\n";
break;
case 6:
cout<<"PostOrder traversal: ";
etree.postOrder(etree.root); cout<<"\n";
break;
case 7:
cout<<"The evaluation result of \""<<expression<<"\" is: "
<<etree.evaluateExpression(etree.root)<<"\n";
break;
case 8:
exit(0);
}
cout<<"*****************************************************************\n";
}
return 0;
}