Receiving stack errors when trying to evaluate a postfix expression in c++ [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am getting 3 errors when I try to use stacks when I want to evaluate a postfix expression. I am not very experienced with the usage of stacks so please be patient with me.
Here is my code:
int Expression::evaluate(string postfix)
{
// ERROR 1 //
stack<int> resultStack = new stack<int>();
int length = postfix.length();
for (int i = 0; i < length; i++)
{
if ((postfix[i] == '+') || (postfix[i] == '-') || (postfix[i] == '*') || (postfix[i] == '/') || (postfix[i] == '^') || (postfix[i] == 'sqrt') || (postfix[i] == 'log') || (postfix[i] == 'abs') || (postfix[i] == '~'))
{
// ERROR 2 //
int result = doTheOperation(resultStack.pop(), resultStack.pop(), postfix[i]);
resultStack.push(result);
}
else if ((postfix[i] >= '0') || (postfix[i] <= '9'))
{
resultStack.push((int)(postfix[i] - '0'));
}
else
{
}
}
// ERROR 3 //
return resultStack;
}
//The operations that must be done if a specific operator is found in the string
int Expression::doTheOperation(int left, int right, char op)
{
switch (op)
{
case '+':
return left + right;
case '-':
return left - right;
case '*':
return left * right;
case '/':
return left / right;
case '^':
return pow(left,right);
case 'sqrt':
if(right < 0)
{
string temp = "Square root of a negative number.";
throw temp;
}
else
{
return (sqrt(right)) ;
}
case 'log':
if (right < 0)
{
string temp = "Error. Not able to get the log of zero.";
throw temp;
}
else
{
int temp = log10(right);
return ceil(temp);
}
case 'abs':
if (right < 0)
{
return (right*-1);
}
else
{
return right;
}
case '~':
return (right*-1);
default:
return -1;
}
return -1;
}
Then it gives me the following errors:
error 1: conversion from 'std::stack<int>*' to non-scalar type 'std::stack<int>' requested
error 2: invalid use of void expression
error 3: cannot convert 'std::stack<int>' to 'int' in return
I will mark in the code where exactly these errors are occuring. I have absolutely no idea why I am getting these errors.

Error 1:
The operator new returns a pointer to a dynamically allocated object (here std::stack<int> *) in the free store, but you just want to create a stack as a local variable (std::stack<int>).
Change the line to:
stack<int> resultStack;
Error 2:
You call resultstack.pop(), certainly expecting that it returns an int and pops it from the stack. unfortunately, pop() is void. It returns nothing, so you can't pass this result as a parameter.
Even if it would return an int, you would have a hidden error: you have no garantee about the order of evaluation of parameters in a function call. So you do not know for sure wich of the two pops is done first.
Change the line to:
int p1 = resultStack.top(); resultStack.pop();
int p2 = resultStack.top(); resultStack.pop();
int result = doTheOperation(p1, p2, postfix[i]);
Error 3:
Your function is defined as returning an int. But you try to return the whole resultStack, which is a stack.
If you want to return just the last value remainint on top of the stack, change the line to:
return resultStack.top()

Related

converting from postfix to infix using stacks

I'm currently working on a project converting from postfix to infix using stacks in the form of linked lists. I'm currently trying to read in the whole line as a string then placing it into a character array then when a symbol is found placing one element into a right operand another into a left operand then printing it back out inlcuding the operator. however after placing the first item into the left operand and then popping the stack im not able to place the other item into the right operand. What could be the problem? I its with my pop fucntion.
Here is my code:
#include "stack.h"
stack::~stack()
{
cout<<"Inside !stack \n";
while(s_top != 0)
{
pop();
}
}
void stack::pop()
{
cout<<"Inside pop \n";
stack_node *p;
if (s_top != 0)
{
p = s_top;
s_top = s_top->next;
delete p;
}
}
void stack::push(char a)
{
cout<<"Inside push \n";
stack_node *p = new stack_node;
p->data = a;
p->next = s_top;
s_top = p;
}
void stack::print()
{
cout<<"Inside print \n";
for(stack_node *p = s_top; p!=0; p=p->next)
{
cout<<p->data<<endl;
}
}
stack_element stack::top()
{
cout<<"Inside top \n";
if (s_top == 0)
{
exit(1);
}
else
{
return s_top->data;
}
}
/*stack::stack(const stack & Org)
{
cout<<"Inside the Copy Constructor\n";
stack_node *p=Org.s_top;
(*this).s_top = 0;
while(p!=0)
{
(*this).push(p->data);
p=p->next;
}
}
and here is my cpp where it doesnt completely work
#include "stack.h"
string convert(string expression){
stack c;
string post = " ";
string rightop="";
string leftop="";
string op =" ";
for (int i =0; i<expression.length();i++){
c.push(expression[i]);
if(expression[i]=='*'||'+'||'-'||'/'){
cout<<c.top()<<endl;
leftop=c.top();
c.pop();
rightop=c.top();
cout<<rightop<<endl;
c.pop();
op=c.top();
c.pop();
}
}
}
int main(){
string expression;
cout<<" Enter a Post Fix expression: ";
getline(cin,expression);
convert(expression);
return 0;
}
Here's an issue:
(expression[i]=='*'||'+'||'-'||'/'
This does not do what you think it does.
The fix:
(expression[i] == '*' ||
expression[i] == '+' ||
expression[i] == '-' ||
expression[i] == '/')
Edit 1: Searching strings
Another method is:
char c = expression[i];
const std::string operators="*+-/";
if (operators.find(c) != std::string::npos)
{
// expression[i] is an operator character
}
The commonly posted solution is to use switch:
switch (expression[i])
{
case '+': Process_Operator_Plus(); break;
case '-': Process_Operator_Minus(); break;
case '*': Process_Operator_Multiply(); break;
case '/': Process_Operator_Divide(); break;
}
Remember, you will need to handle operator precedence when evaluating expressions.

Strangeness with dynamic arrays in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am honestly not quite sure what is going on here.
It has been years since I have programmed in C++, but I am trying to execute this code
short* result = new short[3];
now, I would expect that this creates an array with 3 memory locations: 0,1 and 2, but for what ever reason, this works:
result[0] = someObject::parseShort();
but this does not work:
result[1] = someObject::parseShort();
no exception is thrown, but it is like addresses 1 and 2 dont even exist? I have verified this with visual studio's debugger, and this is leading to some very interesting results when I try to read from those memory addresses, no matter what I Initially wrote to them, they always seem to return 0
Like I said, its been years since I've written anything in C++, and would appreciate someone being able to tel me what is going on? because as far as I can tell, it looks like I am defining the array right?
EDIT:
here is the rest of the relevent code:
phoneNumber::phoneNumber(string number)
{
short* nbrs = parseNumber(number);
areaCode = nbrs[0];
prefix = nbrs[1];
this->number = nbrs[2];
delete[] nbrs;
}
areaCode, prefix, and number are all members of the class.
area code gets set correctly, but prefix and number dont seem to
here is the definition of parseNumber:
short* phoneNumber::parseNumber(string num)
{
if (num == "")
throw new exception("value should not be null");
int var= 3;
short* result= new short[var];
string temp = "";
bool fail = false;
int j = 0;
bool ready = false;
num = Utils::removeSpaces(num);
if (j ==0&&num[0] != '(')
{
fail = true;
}
for (int i = 1; i < num.length(); i++)
{
if (fail)
{
throw exception("Could not parse phone number! Invalid format, expected (xxx)xxx-xxxx");
}
if (num[i] >= '0' && num[i] <= '9')
{
temp+=num[i];
continue;
}
else if (j== 0 && num[i] ==')')
{
if(temp.length() != 3)
{
fail = true;
continue;
}
ready = true;
}
else if(j==1 && num[i] =='-')
{
if(temp.length() != 3)
{
fail = true;
continue;
}
ready = true;
}
else if (j == 3 && i == num.length() -1)
{
if(temp.length() != 4)
{
fail = true;
continue;
}
ready = true;
}
else
{
fail = true;
continue;
}
if (ready)
{
result[j]= Utils::parseShort(temp);
j++;
temp = "";
ready = false;
continue;
}else
{
temp+= num[i];
}
}
if (temp.length()==4)
result[j]= Utils::parseShort(temp);
else
{
throw exception("Could not parse phone number! Invalid format, expected (xxx)xxx-xxxx");
}
return result;
}
Yes, you are defining your array right. You have a bug elsewhere in your code outside the part that constitutes your question.

infix to postfix program

I have written the following infix to postfix program but it's not working.
My program takes input but doesn't show any result. Can anyone help find the problem in my program.
And also it would be a great help if you tell if my Algorithm for converting infix to postfix is correct or not.
using namespace std;
class Stack
{
private:
int top;
char s[mx];
public:
Stack()
{
top=-1;
}
void push(char c)
{
if(!stackFull())
s[++top]=c;
}
void pop()
{
if(!stackEmpty())
top--;
else cout<<"Stack is empty"<<endl;
}
char topShow()
{
if(!stackEmpty())
return s[top];
}
bool stackEmpty()
{
if(top==-1)
return 1;
else return 0;
}
bool stackFull()
{
if(top == (mx-1))
return 1;
else return 0;
}
};
class Expression
{
private:
char entry2;
int precedence;
char infix[mx];
char postfix[mx];
public:
int prec(char symbol)
{
switch(symbol)
{
case '(':return 0; break;
case '-':return 1; break;
case '+':return 2; break;
case '*':return 3; break;
case '/':return 4; break;
}
}
void Read()
{
cout<<"Enter the infix expression: ";cin>>infix;
for(int i=0;infix[i]!='\0';i++)
{
convertToPostfix(infix[i]);
}
}
void ShowResult()
{
cout<<"Postfix expression"<<endl;
for(int j=0;postfix[j]!='\0';j++)
{
cout<<postfix[j];
}
}
void convertToPostfix(char c)
{
int p=0;
Stack myStack;
precedence=prec(c);
entry2=myStack.topShow();
if(isdigit(c))
{
postfix[++p]=c;
}
if(precedence>prec(entry2))
{
myStack.push(c);
}
if(precedence<prec(entry2))
{
switch(c)
{
case '(': myStack.push(c); break;
case ')': while(myStack.topShow()!= '(')
{
postfix[++p]=myStack.topShow();
myStack.pop();
};myStack.pop();break;
case '+':
case '-':
case '*':
case '/': while(prec(myStack.topShow())>=precedence)
{
postfix[++p]=myStack.topShow();
myStack.pop();
};break;
}
}
}
};
int main()
{
Expression myExp;
myExp.Read();
myExp.ShowResult();
return 0;
}
Here are some issues I found:
Boolean Functions Return true or false
Match return types with return values. The numbers 1 and 0 are not Boolean values.
Precedence table
Add and subtract have same precedence.
Multiply and divide have same precedence.
Multiply and divide have higher precedence than add and subtract.
Stack disappears
Since the stack is declared as a local variable in the function, it will be created fresh when entering the function and destroyed before exiting the function.
Solution: move it to the class as a class member or declare it as static.
Multiple statements per line are not more efficient
Blank lines and newlines do not affect performance, and add negligible time to the build.
However, they make your program more readable which helps when inspecting or debugging. Use them.
And similarly with space before and after operators.
Build the habit now rather than correcting when you get a job.
Call function once and store the value
You call prec(entry2) twice, which is a waste of time. Call it once and save the value in a variable. Similarly with stack.TopShow().
Use std::vector not an array
The std::vector will grow as necessary and reduce the chance of buffer overflow.
With an array, you must check that your indices are always within range. Also, array capacities don't change; you have to declare a new instance and copy the data over.
The variable mx is not declared
The compiler should catch this one. You use mx as the capacity for an array and comparing for full. However, it is never declared, defined nor initialized. Prefer std::vector and you won't have to deal with these issues.
Input is not validated
You input a letter, but don't validate it.
Try these characters: space, #, #, A, B, etc.
Missing default for switch
Crank up your compiler warnings to maximum.
Your switch statements need defaults.
What precedence do numeric characters ('0'..'9') have?
(You check the precedence of numeric characters.)
Check all paths through your functions and program.
Using a debugger (see below) or pen and paper, check your program flow through you functions. Include boundary values and values not within the bounds.
Case statements: break or return
You don't need a break after a return statement. Think about it. Can the program continue executing at the line after a return statement?
Use a debugger or print statements
You can print variables at different points in your program. This is an ancient technique when debuggers are not available.
Learn to use a debugger. Most IDEs come with them. You can single step each statement and print out variable values. Very, very, useful.
class infixToPostfix{
public static void postfix(String str){
Stack<Character> stk = new Stack<Character>();
for(Character c : str.toCharArray()){
// If operands appears just print it
if(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z'){
System.out.print(c);
}else{
// Open paranthesis push is
if(c == '('){
stk.push(c);
//Close paranthesis pop until close paranthesis
}else if( c == ')'){
while(stk.peek() != '(')
System.out.print(stk.pop());
stk.pop();
// check the precedence of operator with the top of stack
}else if(c == '+' || c == '-'){
if(!stk.isEmpty()){
char top = stk.peek();
if(top == '*' || top == '/' || top == '+' || top == '-'){
System.out.print(stk.pop());
}
}
stk.push(c);
}else{
if(!stk.isEmpty()){
char top = stk.peek();
if(top == '/' || top == '*'){
System.out.print(stk.pop());
}
}
stk.push(c);
}
}
}
//Print all the remaining operands
while(!stk.isEmpty()) System.out.print(stk.pop());
System.out.println();
}
public static void main(String args[]){
String str = "A+B-(c+d*Z+t)/e";
postfix(str);
}
}
using stack and map u can solve the problem
1) create a map having operator as key and some integer to set priority. operator with same precedence will have same value something like:
map<char,int>oprMap;
oprMap['^'] = 3;
oprMap['*'] = 2;
oprMap['/'] = 2;
oprMap['+'] = 1;
oprMap['-'] = 1;
2) iterate through given expression call these checks
1) if current element
i) is operand add it to result
ii) not operand do following check
a. while not (stack is empty and element is open bracket and found operator with higher precedence.
add top of the stack to the result and pop()
b. push current element to stack
iii) if open brackets push to stack
iv) if closed brackets pop until get closed bracket and add it to result
3) while stack is not empty pop() and add top element to the result.
{
stack<char>S;
for (int i = 0; i < n; i++) {
if(isOperand(exps[i])) {
res = res + exps[i];
} else if(isOperator(exps[i])){
while(!(S.empty() && isOpenParanthesis(S.top()) && isHeigherPrecedence(S.top(),exps[i])){
res = res+S.top();
S.pop();
}
S.push(exps[i]);
} else if(isOpenParanthesis(exps[i])) {
S.push(exps[i]);
} else if(isClosingParanthesis(exps[i])) {
while(!S.empty() && !isOpenParanthesis(S.top())) {
res = res+S.top();
S.pop();
}
S.pop();
}
}
while(!S.empty()) {
res = res + S.top();
S.pop();
}
}
}
#include<bits/stdc++.h>
using namespace std;
// This isHigher function checks the priority of character a over b.
bool isHigher(char a,char b)
{
if(a=='+' || a=='-')
return false;
else if((a=='*' && b=='*') || (a=='*' && b=='/') || (a=='/' && b=='*') ||
(a=='/' && b == '/')|| (a=='^' && b=='^')||(a=='*' && b=='^') || (a=='/' &&
b=='^'))
return false;
return true;
}
int main(){
string s;
cin>>s;
s = s + ")";
//Vector postfix contains the postfix expression.
vector<char>postfix;
stack<char>mid;
mid.push('(');
for(int i=0;i<s.length();i++)
{
if(s[i] == '(')
mid.push(s[i]);
else if(s[i] == '+' || s[i] == '^' || s[i] == '-' || s[i] == '*'||
s[i] == '/')
{
if(mid.top() == '(')
mid.push(s[i]);
else {
if(isHigher(s[i],mid.top()))
mid.push(s[i]);
else
{
while(mid.top()!='(')
{
if(!isHigher(s[i],mid.top()))
{
postfix.push_back(mid.top());
mid.pop();
}
else
break;
}
mid.push(s[i]);
}
}
}
else if(s[i] == ')')
{
while(mid.top() != '(')
{
postfix.push_back(mid.top());
mid.pop();
}
mid.pop();
}
else
postfix.push_back(s[i]);
}
for(int i=0;i<postfix.size();i++)
cout<<postfix[i];
return 0;
}

Infix to postfix algorithm

I've been working on a algorithm to convert "a+b*c-d/e" to it's postfix form. I've ready the http://en.wikipedia.org/wiki/Shunting-yard_algorithm wiki but am having problem with my logic. When I print out my Queue, I get "a b c d e" with no operators. It seems nothing is getting pushed into my Stack? Or if it is, it isn't getting pushed into my Queue. My Queue / Stack is being implemented by a double linked list class I created.
#include <iostream>
#include "LinkedList.h"
#include "Stack.h"
#include "Queue.h"
using namespace std;
int oper(char c)
{
switch(c) {
case '!':
return 4;
case '*': case '/': case '%':
return 3;
case '+': case '-':
return 2;
case '=':
return 1;
}
return 0;
}
int main () {
LinkedList* list = new LinkedList();
string infix = "a+b*c-d/e";
Stack *holder = new Stack();
Queue *newstring = new Queue();
int length = infix.length();
char temp;
char prev;
for(int i=0; i<length; i++)
{
temp = infix[i];
if((temp == '+') || (temp == '-') || (temp == '*') || (temp == '/'))
{
if (holder->isEmpty())
{
holder->push(temp);
prev = temp;
continue;
}
if(oper(temp)<oper(prev))
{
newstring->queue(holder->popStack());
temp = '\0';
continue;
}
else
holder->push(temp);
prev = temp;
}
else
newstring->queue(temp);
}
while(!holder->isEmpty())
{
newstring->queue(holder->popStack());
}
newstring->printQueue();
return 0;
}
your code part ::
if(oper(temp)<oper(prev))
{
newstring->queue(holder->popStack());
temp = '\0';
continue;
}
this part of the code dosent get a hit at all ......
the string provided in the input "a+b*c-d/e"
see this ::
if(oper(temp)<oper(prev))
the condition is to check the priority of the previous operator with respect to the currently scanned one in the variable temp but there is no statement outside the previous if statement(condition where stack is empty) to extract or assign the prev variable from the options available in the stack hence the initial value of "+" is used for evaluation of the if condition which is less than "*" and "\" , and is at the same level with "-" but not greater as a result the second if condition never gets satisfied and dosent get a hit.
thats probably why when you pop nothing comes out of the stack , and thats how you get your current result. you would need to visit the code again and make appropriate changes.
hope this helps , have a nice day ahead.

add unary operator in expression tree

I am doing my assignment in which I have to modify my previous task (which is prefix expression tree which takes expression and give result)
+ OR
* AND
- NOT
Now I have to make it Logic expression tree which will perform AND OR and NOT operations
char input;
cin.get(input);
if((input == '+')||(input == '-')||(input == '*'))
{
p = new ExprTreeNode(input,NULL,NULL);
buildSub(p->left);
buildSub(p->right);
}
else if(isdigit(input))
{ //create a new node
p = new ExprTreeNode(input,NULL,NULL);
}
else
{
cout <<" invalid expression exiting..." <<endl;
exit (1);
}
above code reads expression and makes tree using recursion...
I am confused how I can add unary operator that is NOT...
after that I have to evaluate expression
int answer;
switch (p->dataItem){
case '*':
// AND
case'+':
// OR
case '-':
// Reverse
default:
answer = (p->dataItem-'0');
break;
}
return answer;
p is ExprTreeNode
// Data members
char dataItem; // Expression tree data item
ExprTreeNode *left, // Pointer to the left child
*right; // Pointer to the right child
I'd say you want to do the following:
if ((input == '+') || (input == '*'))
{
p = new ExprTreeNode(input,NULL,NULL);
buildSub(p->left);
buildSub(p->right);
}
else if (input == '-')
{
p = new ExprTreeNode(input, NULL, NULL);
buildSub(p->left);
}
else if(isdigit(input))
{ //create a new node
p = new ExprTreeNode(input,NULL,NULL);
}
else
{
cout <<" invalid expression exiting..." <<endl;
exit (1);
}
Edit:
Then, the evaluation routine could work like this:
bool ExprTreeNode::evaluate() {
switch (dataItem) {
case '+':
return left->evaluate() || right->evaluate();
case '*':
return left->evaluate() && right->evaluate();
case '-':
return !left->evaluate();
case '0':
return false;
default:
return true;
}
}