Reputation: 61
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!
Upvotes: 0
Views: 207
Reputation: 6637
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.
Upvotes: 1