简体   繁体   English

使用堆栈的 C++ 后缀表达式评估。 我认为我没有正确转换数据

[英]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.我目前正在尝试让这个后缀表达式 eval 起作用,但我相信在int EvaluatePostfix函数中我错误地使用了stackPtr->peek()因为每当我尝试获取最高值并将其减去“0”(不是显示在代码中,mb) 将其转换为 int 它说它是一个“std::basic_string-char-”所以它不能用char类型进行减法。

postfix.cpp:后缀.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: 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'"编辑:将stackPtr->peek()减去 '0' 时得到的错误是“与 'operator-' 不匹配(操作数类型为 'std::basic_stringchar' 和 char'”

Thanks!谢谢!

The problem here is that you are using std::string , char , and int interchangeably, while they are not.这里的问题是您可以互换使用std::stringcharint ,而它们不是。

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 .请注意,堆栈的数据类型是string ,并且没有从string更改为int或将string更改为char默认方法。

Based on your descriptions, you were trying to get the first char out of the string , which you would probably call either:根据您的描述,您试图从string获取第一个char ,您可能会调用它:

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. string to int会调用std::stoi(stackPtr->peek()) ,但不确定你是否想要它,因为你自己实现它。

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.因此,当您从堆栈中获取string时,您可以轻松地重用它。

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

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