Jump to content
  • Advertisement
Sign in to follow this  
Edzio

postfix evaluation C++

This topic is 4258 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I am trying to evaluate a postfix expression using the following code - for some reason the program halts just inside the for loop. Anyone with any advice regarding this please help. <source> double evaluate_expression(string& postfix, bool& okay) // Process each line for infix-to-postfix conversion and evaluation { const char DECIMAL = '.'; const char LEFT_PARENTHESIS = '('; const char RIGHT_PARENTHESIS = ')'; stack<double> numbers; stack<char> operations; double number = 0; char symbol = ' '; cout << "inside" << endl; for(int i = 0; i < postfix.size(); ++i) { cout << "inside for" << endl; if(postfix == LEFT_PARENTHESIS) { cout << "inside 1st if" << endl; cin >> symbol; operations.push(symbol); } else if(isdigit(postfix) || (postfix == DECIMAL)) { cin >> number; numbers.push(number); cout<< "First Number " << numbers.top() << endl; } else if(strchr("+-*/", postfix) != NULL) { cin >> symbol; operations.push(symbol); cout<< "First Symbol " << symbol << endl; } else if(postfix == RIGHT_PARENTHESIS) { cin.ignore(); do_operation(symbol, numbers, okay); } else cin.ignore(); } return numbers.top(); } </source> thanks for any help offered

Share this post


Link to post
Share on other sites
Advertisement
You can't use cin here - cin takes input from the standard input (probably what you type). String streams might be a better alternative. These can take input from a string instead of from the user.

However, if you do that, you'll still have another problem: how your for loop is structured means that you will examine every character in the string, even the ones inside the middle of numbers, which you probably didn't want it to.

PS. The source tags need square brackets [smile]

Share this post


Link to post
Share on other sites
Thanks MR EVIL, i think i have altered the code correctly - but am still in the same predicament, the following has changes I 'think' but still does not get past the first if statement.

double evaluate_expression(istream& in, bool& okay)
// Process each line for infix-to-postfix conversion and evaluation
{
const char DECIMAL = '.';
const char LEFT_PARENTHESIS = '(';
const char RIGHT_PARENTHESIS = ')';

stack<double> numbers;
stack<char> operations;
double number;
char symbol;

while(in)
{

if(in.peek() == LEFT_PARENTHESIS)
{
in >> symbol;
operations.push(symbol);
}

if(isdigit(in.peek()) || (in.peek() == DECIMAL))
{
in >> number;
numbers.push(number);
cout<< "First Number " << numbers.top() << endl;
}

else if(strchr("+-*/", in.peek()) != NULL)
{
in >> symbol;
operations.push(symbol);
cout<< "First Symbol " << symbol << endl;

}

else if(in.peek() == RIGHT_PARENTHESIS)
{
in.ignore();
do_operation(symbol, numbers, okay);
}

else
in.ignore();
}
return numbers.top();
}


Share this post


Link to post
Share on other sites
I think the best way to figure this out is to run the code in a debugger and see what it's actually doing. I believe Visual C++ Express to be a good IDE with a well-integrated debugger. Superpig wrote a nice article on debugging, too.

I don't know exactly what you mean when you say it doesn't get past the first if statement. Does it continually find LEFT_PARENTHESIS? Does it mysteriously stop?

Share this post


Link to post
Share on other sites
Hi again,
I figured out the bug from the above code - my command line was waiting for user input. Having got that, the following code runs but it is outputting strange values. Like instead of simply evaluating 2+3 ... somewhere the output is being corrupted to output values in the range of 48 (when I type: 0+0) to 53 (2+3). There is a bit of code that may be involved so I am posting the full program.
Any help would be great.


// CP2001 - 2007
// Assignment 1
// Write a simple calculator program that takes as input an infix expression,
// and outputs the equivalent postfix expression and the evaluation of the infix expression.
// Assume that the input may contain (floating) numbers, arithmetic operations +,-,*, and /,
// as well as parentheses. However, the expression need not b e fully parenthesized,
// and when parentheses are missing, the usual C++ precedence rules are used to determine the order of evaluation.
// When an invalid infix expression is entered, then an error message will be printed and the user will
// be re-prompted to enter a new infix expression. The program will continue until the user type ENTER ('\n') without expressions.

#include <cctype> // Provides isdigit
#include <cstdlib> // Provides EXIT_SUCCESS
#include <cstring> // Provides strchr
#include <iostream> // Provides cout, cin, peek, ignore
#include <stack> // Provides the stack template class
#include <string>
using namespace std;

// PROTOTYPES for functions used by this demonstration program:
void do_operation(char operation, stack<double>& numbers, bool& okay);
double evaluate_expression(string &postfix, bool& okay);
void convert(string& infix, string& postfix);
bool is_operand(char ch);
bool takes_precedence(char operatorA, char operatorB);

int main( )
{
double answer;
bool okay;

do{
string infix;
string postfix;

cout << "================================================================" << endl;
cout << "Type an infix arithmetic expression (Just type ENTER to quit!!):" << endl;
cout << "Infix: ";
cin >> infix;
convert(infix, postfix);

cout << "Postfix: " << postfix << endl;
cout<< "you have gone past postfix" << endl;

answer = evaluate_expression(postfix, okay);

if(okay)
cout << "Evaluation: " << answer << "." << endl;
else
cout << endl << "Invalid infix notation!!" << endl;
}while(true);


system("pause");
return EXIT_SUCCESS;
}

double evaluate_expression(string& postfix, bool& okay)
// Process each line for infix-to-postfix conversion and evaluation
{
const char DECIMAL = '.';
const char LEFT_PARENTHESIS = '(';
const char RIGHT_PARENTHESIS = ')';

stack<double> numbers;
stack<char> operations;
double number;
char symbol;
char hold;
cout << "inside" << endl;
for(int i = 0; i < postfix.size(); i++)
{
hold = postfix;

if(isdigit(postfix) || (postfix == DECIMAL))
{
number = hold;
numbers.push(number);
cout<< "First Number " << numbers.top() << endl;
}

else if(strchr("+-*/", postfix))
{
symbol = hold;
operations.push(symbol);
cout<< "First Symbol " << symbol << endl;
}

else if(postfix == '\n')
{
cin.ignore();
do_operation(symbol, numbers, okay);
}

else
okay = !okay;
}
return numbers.top();
}

void do_operation(char operation, stack<double>& numbers, bool& okay)
// Pops two numbers from s, applies the operation, and pushes the answer
// back on the stack s. Sets okay to false if any errors are found,
// but leaves okay alone if there are no errors.
{
double operand1;
double operand2;

operand2 = numbers.top();
numbers.pop();
operand1 = numbers.top();
numbers.pop();
switch(operation)
{
case '+': numbers.push(operand1 + operand2);
break;
case '-': numbers.push(operand1 - operand2);
break;
case '*': numbers.push(operand1 * operand2);
break;
case '/': numbers.push(operand1 / operand2);
break;
default: okay = !okay;
}
}

bool is_operand(char ch)
{
if(((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9')))
return true;
else
return false;
}

bool takes_precedence(char operatorA, char operatorB)
{
if(operatorA == '(')
return false;
else if(operatorB == '(')
return false;
else if(operatorB == ')')
return true;
else if((operatorA == '^') && (operatorB == '^'))
return false;
else if(operatorA == '^')
return true;
else if(operatorB =='^')
return false;
else if((operatorA == '*') || (operatorA == '/'))
return true;
else if((operatorB == '*') || (operatorB == '/'))
return false;
else
return true;
}

void convert(string& infix, string& postfix)
{
stack<char> hold_symbol;
char top_symbol;
char symbol;

for(int i = 0; i < infix.size(); ++i)
{
symbol = infix;
if(is_operand(symbol))
postfix = postfix + symbol;
else
{
while((!hold_symbol.empty()) && (takes_precedence(hold_symbol.top(), symbol)))
{
top_symbol = hold_symbol.top();
hold_symbol.pop();
postfix = postfix + top_symbol;
}
if((!hold_symbol.empty()) && (symbol == ')'))
hold_symbol.pop();
else
hold_symbol.push(symbol);
}
}
while(!hold_symbol.empty())
{
top_symbol = hold_symbol.top();
hold_symbol.pop();
postfix = postfix + top_symbol;
}
}




Again, thanks for any info...

Share this post


Link to post
Share on other sites
Thanks sirGustav,
Sorry, but im not sure what you mean, is that just a test? or an example of changes to the code?

Share this post


Link to post
Share on other sites
Hi Again - In my screen swapping i seem to have lost the last message posted by sirGustav. If you are still there, could you re-post it???? is there any reason why the last few posts would dissappear from the forum??

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!