简体   繁体   English

使用队列和堆栈进行后缀评估 c++

[英]postfix evaluation using queues and stacks c++

main code Associated files will be linked to github主要代码相关文件将链接到github

https://github.com/andrew-chen/csis252/blob/master/examples/token/token.h 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/stackType.h

https://github.com/andrew-chen/csis252/blob/master/examples/queueType.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 token.cpp 没有链接,所以我将复制并粘贴到这里

// 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.无论出于何种原因,我的副本 copyresutQue 都会删除一些队列,并且不会将它们推送到我的 newResult 堆栈中。 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.由于在 pop() 操作数执行评估的算术部分时删除了来自 copyresutQue 的队列,因此它将在我的代码中显示空堆栈错误,因为没有任何内容可以从 newResult 堆栈中弹出。

Exmaple: input (10+3)-2 infix expression 10 3 + 2-示例:输入 (10+3)-2 中缀表达式 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.它将添加 10 + 3 并将 13 推入新结果堆栈,但随后会显示错误,因为无论出于何种原因,队列的 rest 都将被删除。 Also the rest of the files are given by the instructor so they should be 100% correct.此外,文件的 rest 由讲师提供,因此它们应该是 100% 正确的。 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循环有一些问题。

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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