I am trying to convert infix to postfix and prefix by using tree in c++. I pass the infix expression to the createTree function and in the code I use 2 stack node(to store the operand and operator that has been poped from the stack s) and stack s(to store the operator). The code works finely when I input expression that has same precedence operators or the first operator has higher precedence than the second one. ex: 1*2/3 or 1/2+3. But it will debug when I input expressions which the first operator has lower precedence than the second one. for example : 1+2/3. I try to debug it and found DEBUG_ERROR("iterator not dereferencable"); I try to find in the internet and all those problems related to vector which I have never used before. I hope you guys could help me
node *CreateTree(string post)
{
node *temp, *op1 , *op2;
stack<node*> tree;
stack<char> s;
int i = 0;
while (!tree.empty())
{
tree.pop();
}
for(i = 0; i<post.length();i++)
{
if (post[i]==' ') continue;
else if(IsOperand(post[i]))
{
node *temp = new node();
temp->in = post[i];
temp->left = NULL;
temp->right = NULL;
for(int j=i+1;j<post.length();j++)
{
if (IsOperand(post[j]))
{
temp->in+=post[j];
i = j;
}
else break;
}
tree.push(temp);
}
else if(isOperator(post[i]))
{
while(!s.empty() && s.top()!='(' && s.top()!='{' && s.top()!='[' && !hasHigherPrecedence(post[i],s.top()))
{
node *op1;
node *op2;
op2 = tree.top();
tree.pop();
op1 = tree.top();
tree.pop();
node *temp = new node();
temp->in = s.top();
temp->left = op1;
temp->right = op2;
root = temp;
s.pop();
tree.push(root);
}
s.push(post[i]);
}
else if(post[i]=='(')
{
s.push(post[i]);
}
else if(post[i]==')')
{
while(s.top()!='('&&!s.empty())
{
node *op1;
node *op2;
op2 = tree.top();
tree.pop();
op1 = tree.top();
tree.pop();
node *temp = new node();
temp->in = s.top();
temp->left = op1;
temp->right = op2;
root = temp;
s.pop();
tree.push(root);
}
s.pop();
}
else if(post[i]=='[')
{
s.push(post[i]);
}
else if(post[i]==']')
{
while(s.top()!='['&&!s.empty())
{
node *op1;
node *op2;
op2 = tree.top();
tree.pop();
op1 = tree.top();
tree.pop();
node *temp = new node();
temp->in = s.top();
temp->left = op1;
temp->right = op2;
root = temp;
s.pop();
tree.push(root);
}
s.pop();
}
else if(post[i]=='{')
{
s.push(post[i]);
}
else if(post[i]=='}')
{
while(s.top()!='{'&&!s.empty())
{
node *op1;
node *op2;
op2 = tree.top();
tree.pop();
op1 = tree.top();
tree.pop();
node *temp = new node();
temp->in = s.top();
temp->left = op1;
temp->right = op2;
root = temp;
s.pop();
tree.push(root);
}
s.pop();
}
else cout<<post[i]<<" is not registered as operator or operand";
}
while (!s.empty())
{
node *op1;
node *op2;
op2 = tree.top();
tree.pop();
op1 = tree.top();
tree.pop();
node *temp = new node();
temp->in = s.top();
temp->left = op1;
temp->right = op2;
root = temp;
s.pop();
}
return root;
}
below is the functions that are called in code above
bool isOperator(char a)
{
return(a=='+' || a=='*' || a=='^' || a=='/' ||
a=='-' || a=='%')? true:false;
}
int getWeight(char op)
{
int weight;
switch(op)
{
case '+' : case '-':
weight = 1;
break;
case '*':
case '/':
case '%':
weight = 2;
break;
case '^':
weight = 3;
break;
}
return weight;
}
bool hasHigherPrecedence(char a, char top)
{
int aW = getWeight(a);
int tW = getWeight(top);
return (aW > tW)? true : false;
}
tree.top()whentreeis empty. If other code were correcttreecould not be empty at that point. But since it is not locally obvious thattreeisn't empty, you should have at least anassertand maybe a run time check. - JSFsis not empty at the point where you uses.top(). But the same is not true oftree. Even if you were not debugging a current problem, it is good practice to have an assert where your code makes an assumption (tree.size()>=2) that is not locally obvious. - JSFnode *op2 = new node();is NOT related to the problem you are trying to diagnose, but should also be fixed. It is best to delay declaring the variable until you have its correct initial valuenode *op2 = tree.top();. Alternately it is OK to just declare it without an initial valuenode *op2;as long as a compiler can easily see that all paths from there that use it also initialize it. If neither of those fits, then initialize to 0node *op2=0;rather than creating an object just to leak it. C++ is not Java - JSF