首页 > 解决方案 > 使用堆栈的 C++ 后缀表达式求值。我认为我没有正确转换数据

问题描述

我目前正在尝试让这个后缀表达式 eval 工作,但我相信在int EvaluatePostfix我使用stackPtr->peek()不正确的函数中,因为每当我尝试获取最高值并将其减去“0”(代码中未显示,mb)以进行转换它到 int 它说它是一个“std::basic_string-char-”所以它不能用 char 类型做减法。

后缀.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

编辑:减去stackPtr->peek()'0'时得到的错误是“'operator-'不匹配(操作数类型是'std :: basic_stringchar'和char'”

谢谢!

标签: c++pointersstack

解决方案


这里的问题是您正在使用std::string,charint互换,而它们不是。

请注意,您的堆栈数据类型是string,并且没有从stringtointstringto更改的默认方式char

根据您的描述,您试图从 中获得第一个charstring您可能会称之为:

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

或者

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

stringtoint会打电话std::stoi(stackPtr->peek()),但不确定你是否想要它,因为你正在自己实现它。

因此,您可能希望将此部分提取为单独的函数:

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

string因此,当您从堆栈中获取 a 时,您可以轻松地重用它。


推荐阅读