I am writing a program to input an infix expression, convert to postfix, and then evaluate. Converting to postfix isn't the problem, but evaluating the expression is giving me odd answers. Simple expression like 1+1 is giving me 12 as an answer. I cannot figure out what the problem is.

Thanks for any help.

// This program will input a user defined file of mathmatical expressions
// and provide answers to an output file.

#include <iostream> //Required for cin & cout
#include <fstream>  //Required for input & output file functions
#include <stack>    //Required for stack
#include <string>   //Required for string functions
#include <cctype>   //Required to test for number
#include <cmath>    //Required for pow() function
#include <cstdlib>
 
using namespace std;

void toPostfix(string &infix, string &postfix);
int priority(char o);
bool isOperator(char c);
double evaluate(string &postfix);


int main()
{
    //Define variables
    
    string file, infix, postfix;
    double num1, num2;
    
    cout << "Enter an infix expresstion: ";
    cin >> infix;
    
    toPostfix(infix, postfix);
    
    cout << endl << "Postfix expression is : " << postfix << endl;
    cout << infix << " = " << evaluate(postfix) << endl;
	
    system ("pause");
	return 0;
    
}


void toPostfix(string &infix, string &postfix)
{
     stack<char> op; 
     int j=0;

    for(int i=0;i<infix.size();i++)
     {            
         if(isOperator(infix[i]))
         {
             if(op.empty())
             {
                 op.push(infix[i]);
             }
             else if(priority(op.top()) >= priority(infix[i]))
             {
                 postfix += op.top();
                 op.pop();
                 --i;
             }
             else
             {
                 op.push(infix[i]);
             }
         }
         else if(infix[i]=='(')
         {
              op.push('(');
         }
         else if(infix[i]==')')
         {
              while(op.top()!='(')
              {
                 postfix += op.top();
                 op.pop();
              }
              
              op.pop();
         }
         else
         {
             postfix += infix[i];
         }
         }
         while(!op.empty())
         {
             postfix += op.top();
             op.pop();
         }
}

int priority(char o)
{
    switch(o)
    {
        case '-':
        case '+': return 1;
        case '*':
        case '/': return 3;
        case '^': return 5;
        default : return 0;
    }
}

bool isOperator(char c)
{
     if(c=='+'||c=='-'||c=='*'||c=='/'|c=='^') return true;
     else return false;
}


double evaluate(string &postfix)
{
       char *pEnd;
       double num1, num2, answer;
       stack<double> eval;
              
       for(int i=0;i<postfix.size();i++)
       {
            cout << postfix[i] << endl;
            if(isdigit(postfix[i]))     // If the next item in postfix expression is a number, push onto stack
                eval.push(strtod(&postfix[i], &pEnd));
            else                       // Else pop off last two numbers in stack and operate, the push answer back onto stack
            {
                                       
            switch (postfix[i])
            {
                   case '+':
                   num2=eval.top();
                   eval.pop();
                   num1=eval.top();
                   eval.pop();
                   eval.push(num1+num2);
                   break;

                   case '-':
                   num2=eval.top();
                   eval.pop();
                   num1=eval.top();
                   eval.pop();
                   eval.push(num1-num2);
                   break;
                   
                   case '*':
                   num2=eval.top();
                   eval.pop();
                   num1=eval.top();
                   eval.pop();
                   eval.push(num1*num2);
                   break;
                   
                   case '/':
                   num2=eval.top();
                   eval.pop();
                   num1=eval.top();
                   eval.pop();
                       if(num2==0)
                           cout << "Error!  Can not divide by zero!";
                       else
                           eval.push(num1/num2);
                   break;
                   
                   case '^':
                   num2=eval.top();
                   eval.pop();
                   num1=eval.top();
                   eval.pop();
                   eval.push(pow(num1, num2));
                   break;
            }
                   
            }       
                
       }
       
       answer = eval.top();
       eval.pop();
       
       return answer;
}

Edited 6 Years Ago by crazymidget01: n/a

You need to do a rethink here.

119.            cout << postfix[i] << endl;

This gives a little insight as to what your program is doing with the input.

eg postfix
1+1 -> 11+
12+34 -> 1234+
12+34-56 -> 1234+56-

You then switch using the last operand listed in postfix.

How is your program supposed to "know" which number belongs where?

By compiling your program and stopping it you can see what's going on.

//big snip
125      switch (postfix[i])
126      {
127        case '+':
128          num2=eval.top();
129          eval.pop();
130          num1=eval.top();
131          eval.pop();
132          eval.push(num1 + num2);
133            break;
134        
135        case '-':
             ....
  //another snip

Using the above examples and the snippet of code:

1+1
..postfix = 11+
..num2 = 1
..num1 = 11
..output = 12

12+34
..postfix = 1234+
..num2 = 4
..num1 = 34
..output = 38

12+34-56
..postfix = 1234+56-
..num2 = 4
..num1 = 34 -> //first run (these values are ignored)
....postfix = 1234+56-
....num2 = 6
....num1 = 56
....output = 50


Have another little think about it.

David

Edited 6 Years Ago by Dingbats: n/a

This article has been dead for over six months. Start a new discussion instead.