简体   繁体   中英

postfix evaluation using queues and stacks c++

main code Associated files will be linked to github

https://github.com/andrew-chen/csis252/blob/master/examples/token/token.h

https://github.com/andrew-chen/csis252/blob/master/examples/stackType.h

https://github.com/andrew-chen/csis252/blob/master/examples/queueType.h

token.cpp has no link so i will copy and paste onto here

// File:      token.cpp
// This file contains the specification for the token class.  
#include <cmath>
#include <cassert>
#include <cctype>
#include "token.h"
/*
{
      static bool unary; // to identify unary minus
      bool isnumber;     // identify whether it's a number or not
      double value;      // an operand
      char ch;           // an operator or parenthesis
      bool valid;        // true if Token is valid
}
*/
Token::      Token()                         // no argument constructor
{
    valid=false;
};

Token::      Token(double d)                   // double constructor
{
    value = d;
    valid=true;
    isnumber = true;
};
Token::      Token(int i)                      // int constructor
{
    value = i;
    valid = true;
    isnumber = true;
};
Token::      Token(char c)                     // char constructor
{
    ch = c;
    isnumber = false;
    switch (ch) {
        case '(': 
        case ')': 
        case '+': 
        case '-': 
        case '*': 
        case '/': 
        case '%': 
        case '^': 
            valid = true;
            return;
        default:
            valid = false;
    };
};

bool Token::      Valid() const              // true if token is valid
{return valid;};
bool Token::      IsOperand() const          // true if token is an operand
{return isnumber;};
bool Token::      IsOperator() const         // true if token is an operator
{
    switch(ch) {
        case '+':
        case '-':
        case '*':
        case '/':
        case '%':
        case '^':
            return true;
        default:
            return false;
    };
};
bool Token::      IsLeftParen() const        // true if token is a (
{
    return (ch == '(');
};
bool Token::      IsRightParen() const       // true if token is a )
{
    return (ch == ')');
};
double Token::      Operand() const          // returns the value of the operand
{
    return value;
};
char Token::      Operator() const           // returns '+' '-' '*' '/' '%' '^' 
{
    return ch;
};
int Token::      Precedence() const          // returns precedence of operator
{
    switch(ch) {
        case '(': return 0;
        case ')': return 0;
        case '^': return 3;
        case '*': return 2;
        case '/': return 2;
        case '%': return 2;
        case '+': return 1;
        case '-': return 1;
        default: return 0;
    };
};

Token Token::      operator + (const Token & arg) const // add Token to object
{
    return Token(value + arg.value);
};
Token Token::      operator - (const Token& arg) const // subtract Token from object
{
    return Token(value - arg.value);
};
Token Token::      operator * (const Token& arg) const // multiply object by Token
{
    return Token(value * arg.value);
};
Token Token::      operator / (const Token& arg) const // divide object by Token
{
    return Token(value / arg.value);
};
Token Token::      operator % (const Token& arg) const // modulus object by Token
{
    return Token(int(value) % int(arg.value));
};
Token Token::      operator ^ (const Token& arg) const // raise object to power of Token
{
    return Token(pow(value,arg.value));
};
istream& operator >> (istream&i,Token&t) // overload input
{
    char c;
    i.get(c);
    if (isdigit(c)) {
        i.putback(c);
        int v;
        i >> v;
        t = Token(v);
    } else {
        t = Token(c);
    };
    return i;
};
         // A friend function is a none member function that is given access
         // to the private members of a class. Friend functions should be
         // avoided if possible.
         // The >> operator will skip blanks and tabs, not '\n'.
         // '\n' will be read and the token is not valid.
         // This provides a way to have a loop read one line of tokens 
         // then exit when '\n is read.


ostream& operator << (ostream&o,const Token&t) //overload output
{
    assert(t.Valid());
    if (t.IsOperand()) {
        o << t.Operand();
    } else {
        o << t.Operator();
    };
    return o;
};



#include "token.h"
#include "queueType.h"
#include "stackType.h"
#include <iostream>
using namespace std;
int main()
{

    queueType<Token> resultQue;
    stackType<Token> movingStack;
    stackType<Token> newResult;
    queueType<Token> copyresutQue;
    char exponent = '^';
    Token t;
    cout << "enter infix expression: ";
    cin >> t;
    while(t.Valid()){
        if(t.IsOperand()){
            resultQue.addQueue(t);
        }
        else if(t.IsLeftParen()){
            movingStack.push(t);
        }
        else if(t.IsRightParen()){
            while(!movingStack.isEmptyStack()){
                if(movingStack.top().IsOperator()){
                    resultQue.addQueue(movingStack.top());
                    movingStack.pop();

                }
                if(movingStack.top().IsLeftParen()){
                    movingStack.pop();
                    break;
                }


            }
        }
        else if(t.IsOperator()){
            while(!movingStack.isEmptyStack()){
                if(movingStack.top().IsOperator()){
                    if(movingStack.top().Operator()==exponent || t.Precedence()>movingStack.top().Precedence() ||movingStack.top().IsLeftParen() ){
                        break;
                    }
                    resultQue.addQueue(movingStack.top());
                    movingStack.pop();
                }
                else if(movingStack.top().IsLeftParen()){
                    break;
                }
            }
            movingStack.push(t);

        }



        cin >> t;

    }
    while(!movingStack.isEmptyStack()){
        if(movingStack.top().IsOperator()){
            resultQue.addQueue(movingStack.top());
            movingStack.pop();
        }
    }
//    while(!movingStack.isEmptyStack()){
//        cout << movingStack.top() << endl;
//        movingStack.pop();
//    }

    cout << "PostFit Express" <<endl;
    while(!resultQue.isEmptyQueue()){
        cout << resultQue.front()<< " ";
        copyresutQue.addQueue(resultQue.front());
        resultQue.deleteQueue();
    }
    cout << "\ncopy Result"<<endl;
    while(!copyresutQue.isEmptyQueue()) {
        cout << copyresutQue.front()<<endl;
        if (copyresutQue.front().IsOperand()) {
            newResult.push(copyresutQue.front());
            copyresutQue.deleteQueue();
//            cout << copyresutQue.front() <<endl;
        }
        if(copyresutQue.front().IsOperator()){
            Token result;
            while(!newResult.isEmptyStack()){
//                cout << newResult.top()<<endl;
                if(newResult.top().IsOperand()){
                    Token num1 = newResult.top().Operand();
//                    cout << num1 << endl;
                    newResult.pop();
                    Token num2 = newResult.top().Operand();
//                    cout<<num2<<endl;
                    newResult.pop();
                    cout << newResult.top()<<endl;

                    switch (copyresutQue.front().Operator())
                    {
                      case '+' :  result = num2 + num1; break;
                      case '-' :  result = num2 - num1; break;
                      case '*' :  result = num2 * num1; break;
                      case '/' :  result = num2 / num1; break;
                      case '%' :  result = num2 % num1; break;
                      case '^' :  result = num2 ^ num1; break;
                    }
//                    cout<<result<<endl;
                    newResult.push(result);

                }
            }
            copyresutQue.deleteQueue();

        }
//        cout << newResult.top()<<endl;
//        copyresutQue.deleteQueue();


    }

    return 0;
}

so far i have been able to convert the infix to a postfix expression, now my issue is the postfix evaluation. For whatever reason my copy copyresutQue deletes the some of the queues and will not push them onto my newResult stack. Since the queues from copyresutQue are deleted when the pop() the operands to do the arithmetic portion of the evaluation it will display a empty stack error in my code since there is nothing to pop from the newResult stack.

Exmaple: input (10+3)-2 infix expression 10 3 + 2-

it will add 10 + 3 and push 13 onto the newresult stack, but will then display error because for whatever reason the the rest of the queue will have been deleted. Also the rest of the files are given by the instructor so they should be 100% correct. for this assignment i have to use Queues and stacks, I know theres other ways to complete this assignment. Thank you for your time.

The last while loop had some problem.

while(!copyresutQue.isEmptyQueue()) {
    if(copyresutQue.front().IsOperand()) {
        newResult.push(copyresutQue.front());
        copyresutQue.deleteQueue();
    }
    else {
        Token result;
        Token num1 = newResult.top();
        newResult.pop();
        Token num2 = newResult.top();
        newResult.pop();
        auto binaryOperator = copyresutQue.front();
        copyresutQue.deleteQueue();
        cout << binaryOperator << endl;
        switch (binaryOperator.Operator())
        {
          case '+' :  result = num2 + num1; break;
          case '-' :  result = num2 - num1; break;
          case '*' :  result = num2 * num1; break;
          case '/' :  result = num2 / num1; break;
          case '%' :  result = num2 % num1; break;
          case '^' :  result = num2 ^ num1; break;
        }
        newResult.push(result);


    }
}
cout << newResult.top()<<endl;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM