//*****************************************************************************
// Postfix expression evaluation
// 11/13/2012
// by DJH
//
// all applicable copyrights apply
//
// this program evaluates an input postfix string
//
//
// created using Dev-C++ 5.2.0.3
//*****************************************************************************
// ----------------------------------libraries---------------------------------
#include <iostream> // For cin, cout and endl
#include <string>
#include <cctype>
#include <vector>
#include <sstream>
#include <cstdlib>
#include <cmath>
#include <iomanip>
using namespace std;
// ------------------------------ Globals -------------------------------------
string postfix;
// --------------------------- stack class ------------------------------------
class Stack{
public:
enum {MaxStack = 50};
void init() {top = -1;}
void push( double p ){
if ( isFull() ) {
cerr << "Full Stack. DON'T PUSH\n";
return;
}
else {
arr[ ++top ] = p;
cout << "Just pushed " << p << endl;
return;}
}
int pop() {
if (isEmpty() ) {
cerr << "\tEmpty Stack. Don't Pop\n\n";
return 1;
}
else
return arr[top--];
}
bool isEmpty() {return top < 0 ? 1 : 0;}
bool isFull() {return top >= MaxStack -1 ? top : 0;}
void dump_stack() {
cout << "The Stack contents, from top to bottom, from a stack dump are: " << endl;
for (int s = top; s >= 0; s--)
cout << "\t\t" << arr[s] << endl;
}
private:
int top;
double arr[MaxStack];
}pStack;
// ------------------------------ end stack class -----------------------------
// -----------------------------function prototypes----------------------------
void evalPostfix (string);
double decimalEvaluate (string, int, double);
// ----------------------------------------------------------------------------
// -----------------------------------Main()-----------------------------------
int main()
{
cout << "Enter a postfix expression\n\t (without spaces - using '_' for delimiters):\n\t";
cout << "For example: 8_5_3_+_*_2_/_5_+\n" << endl;
getline(cin, postfix);
// postfix = "7_2_*_5_+_2_*";
cout << "You entered: " << postfix << endl;
int c=0;
while ( postfix[c] !='\0' )
{
++c; // this loop counts the characters in the input string including whitespace
}
cout << "\tThe string length is:\t" << c << endl;
evalPostfix (postfix);
int result = pStack.pop();
cout << "The result of the postfix expression is: " << result << endl;
/*
stack commands:
Stack a_stack; // creates new stack
a_stack.init(); // initializes top element
a_stack.pop(); // pops top of stack
a_stack.push(n); // push element to top of stack
a_stack.dump_stack(); // displays the contents of the stack from top to bottom
*/
return 0;
cin.get();
}
// --------------------------------end of Main()-------------------------------
// ------------------------------functions follow------------------------------
void evalPostfix (string)
{
double ch=0,dc=0,b=0,a=0,d=0;
double tempDC=0;
double tempDCD=0;
char op;
int i=0,j=0,k=0,m=0,n=0,q=0;
while (postfix[i] != '\0')
{
if (postfix[i] == '_') {i++;}
else if (isdigit (postfix[i]))
{
ch = postfix[i] - '0'; // for numbers only
j=i+1;
while (postfix[j] != '_')
{
if (isdigit (postfix[j]))
{
ch = ch*10 + (postfix[j] - '0');
k=j+1;
if (postfix[k] == '.') // this accounts for decimals by skipping the '.' and conducting operations on trailing numbers
{
dc=0;
decimalEvaluate (postfix, k, dc);
dc = tempDC / tempDCD;
d=ch+dc;
k++;
}
j=k-1;
j++;
}
}
cout << "Post decimal function k: " << k << endl;
cout << "Post decimal function dc: " << setprecision (12) << dc << endl;
cout << "Post decimal function d: " << d << endl;
pStack.push(d);
i=j-1;
i++;
}
else if (postfix[i] == '+' || postfix[i] == '-' || postfix[i] == '*' || postfix[i] == '/' || postfix[i] == '^')
{
b=pStack.pop();
a=pStack.pop();
op = postfix[i]; // for operators only
switch(op)
{
case '+':pStack.push(a+b);
break;
case '-':pStack.push(a-b);
break;
case '*':pStack.push(a*b);
break;
case '^':pStack.push(pow(a,b));
break;
case '/':if(b==0)
{
cout << "Division by zero not allowed!" << endl;
cin.get();
exit(0);
}
pStack.push(a/b);
default:cout << "Invalid Operation" << endl;
}
i++;
}
}
}
// ----------------------------------------------------------------------------
double decimalEvaluate (string postfix, int k, double dc)
{
dc=0;
double tempDC=0;
double tempDCD=0;
int n=0, m=0,lenDC=0;
n=k;
while ( postfix[n] != '_' )
{
if ((isdigit (postfix[n]))== false)
{
n++;
}
cout << "This step (1) n: " << n << endl;
if (isdigit (postfix[n]))
{
m=n;
while ( postfix[m] != '_' ) // assumes characters between a '.' and '_' are all digits (may need to check)
{
lenDC++;
m++; // this loop counts the digits in the input trailing a decimal point
}
cout << "This step (2) m: " << m << endl;
cout << "This step (2) lenDC: " << lenDC << endl;
while ((postfix[n]) != '_')
{
tempDC = tempDC*10 + (postfix[n]) - '0';
n++;
}
cout << "This step (3) n: " << n << endl;
cout << "This step (3) tempDC: " << tempDC << endl;
}
k=n;
tempDCD = pow(10,lenDC);
dc = tempDC / tempDCD;
cout << "This step (4) k: " << k << endl;
cout << "This step (4) tempDCD: " << tempDCD << endl;
cout << "This step (4) tempDC: " << tempDC << endl;
cout << "This step (4) dc: " << dc << endl;
}
return dc,k,tempDC,tempDCD;
}