简体   繁体   中英

C++ Postfix expression evaluation using stacks. I dont think I'm converting the data correctly

I'm currently trying to get this postfix expression eval to work but I believe within the int EvaluatePostfix function I'm using stackPtr->peek() incorrectly because whenever I try and get the top value and subtract it by '0' (not shown in code, mb) to convert it to int it says it's a "std::basic_string-char-" so it cant do the subtraction with type char.

postfix.cpp:

#include <iostream>
#include <string>
#include "ArrayStack.h"


bool IsNumericDigit(char C)
{
    if(C >= '0' && C <= '9') return true;
    return false;
}

// Function to verify whether a character is operator symbol or not.
bool IsOperator(char C)
{
    if(C == '+' || C == '-' || C == '*' || C == '/')
        return true;

    return false;
}

// Function to perform an operation and return output.
int PerformOperation(char operation, int operand1, int operand2)
{
    if(operation == '+') return operand1 +operand2;
    else if(operation == '-') return operand1 - operand2;
    else if(operation == '*') return operand1 * operand2;
    else if(operation == '/') return operand1 / operand2;

    else std::cout<<"Unexpected Error \n";
    return -1;
}

int EvaluatePostfix(std::string expression, StackInterface<std::string>* stackPtr)
{
    

    for(int i = 0;i< expression.length();i++)
    {

        // Scanning each character from left.
        // If character is a delimiter, move on.
        if(expression[i] == ' ' || expression[i] == ',') continue;

            // If character is operator, pop two elements from stack, perform operation and push the result back.
        else if(IsOperator(expression[i]))
        {
            
            // Pop two operands.
            int operand2 = stackPtr->peek(); 
            stackPtr->pop();
            int operand1 = stackPtr->peek(); 
            stackPtr->pop();
            
            //operand1 and operand2 are reversed in case of Prefix Expression
            
            // Perform operation
            int result = PerformOperation(expression[i], operand1, operand2);
            //Push back result of operation on stack.
            stackPtr->push(result);
        }
        else if(IsNumericDigit(expression[i]))
        {
            // Extract the numeric operand from the string
            // Keep incrementing i as long as you are getting a numeric digit.
            int operand = 0;
            while(i<expression.length() && IsNumericDigit(expression[i]))
            {
                // For a number with more than one digits, as we are scanning from left to right.
                // Everytime , we get a digit towards right, we can multiply current total in operand by 10
                // and add the new digit.
                operand = (operand*10) + (expression[i] - '0');
                std::cout << operand << std::endl;
                i++;
            }
            // Finally, you will come out of while loop with i set to a non-numeric character or end of string
            // decrement i because it will be incremented in increment section of loop once again.
            // We do not want to skip the non-numeric character by incrementing i twice.
            i--;

            // Push operand on stack.
            stackPtr->push(operand);
        }
    }
    // If expression is in correct format, Stack will finally have one element. This will be the output.
    return stackPtr->top();
}

int main(){
    StackInterface<std::string>* stackPtr = new ArrayStack<std::string>();
    std::string expression;
    std::cout<<"Enter Postfix Expression \n";
    std::getline(std::cin,expression);
    EvaluatePostfix(expression, stackPtr)
    std::cout << stackPtr->push(expression);
    
}

ArrayStack.h:

#ifndef ARRAY_STACK_EXCEPTIONS
#define ARRAY_STACK_EXCEPTIONS

#include "StackInterface.h"
#include "PrecondViolatedExcep.h"

const int MAX_STACK = 1000;

template<class ItemType>
class ArrayStack : public StackInterface<ItemType>
{
private:
    ItemType items[MAX_STACK]; // Array of stack items
    int      top;              // Index to top of stack
    
public:
     ArrayStack();
     bool isEmpty() const;
     bool push(const ItemType& newEntry);
     bool pop();
     ItemType peek() const; 
}; // end ArrayStack


template<class ItemType>
ArrayStack<ItemType>::ArrayStack() : top(-1)
{
}  // end default constructor

// Copy constructor and destructor are supplied by the compiler

template<class ItemType>
bool ArrayStack<ItemType>::isEmpty() const
{
    return top < 0;
}  // end isEmpty

template<class ItemType>
bool ArrayStack<ItemType>::push(const ItemType& newEntry)
{
    bool result = false;
    if (top < MAX_STACK - 1)
    {
        // Stack has room for another item
        top++;
        items[top] = newEntry;
        result = true;
    }  // end if
    
    return result;
}  // end push


template<class ItemType>
bool ArrayStack<ItemType>::pop()
{
    bool result = false;
    if (!isEmpty())
    {
        result = true;
        top--;
    }  // end if
    
    return result;
}  // end pop


template<class ItemType>
ItemType ArrayStack<ItemType>::peek() const
{
    // Enforce precondition
    if (isEmpty())
        throw PrecondViolatedExcep("peek() called with empty stack");
        
        // Stack is not empty; return top
        return items[top];
}  // end peek

Edit: The error I get when subtracting stackPtr->peek() by '0' is "no match for 'operator-' (operand types are 'std::basic_stringchar' and char'"

Thanks!

The problem here is that you are using std::string , char , and int interchangeably, while they are not.

Notice that your data type for you stack is string , and there isn't default way to change from string to int or string to char .

Based on your descriptions, you were trying to get the first char out of the string , which you would probably call either:

c = stackPtr->peek()[0];

or

c = stackPtr->peek().front();

string to int would call std::stoi(stackPtr->peek()) , but not sure if you want it as you are implementing it yourself.

So you probably want to extract this part as a separate function:

while(i<expression.length() && IsNumericDigit(expression[i]))
{    
    operand = (operand*10) + (expression[i] - '0');
    std::cout << operand << std::endl;
    i++;
}

so you can easily reuse it when you get a string from your stack.

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