Click here to Skip to main content
15,886,873 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Similar to the following test cases, it should only print the error and not the postfix expression.

Enter an infix expression: +
Error: invalid number of operands
Enter an infix expression: 1+
Error: invalid number of operands
Enter an infix expression: +1
Error: invalid number of operands
Enter an infix expression: 1-+4
Error: invalid number of operands


I have tried modifying the print_postfix function so that it would print the expression under the condition that the stack is empty. However, I realized that the stack will also be empty for valid infix expressions.

What I have tried:

C++
#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>

using namespace std;

const int MAX_SIZE = 100;

class Stack{
  private:
    int top;
    string stackArray[MAX_SIZE];

  public:
    Stack(){
      top = -1;
    }

    void push(string s){
      if(top >= (MAX_SIZE - 1)){
        cout << "Stack Overflow";
      }
      else{
        top++;
        stackArray[top] = s;
      }
    }

    string pop(){
      if(top < 0){
        return "";
      }
      else{
        string s = stackArray[top];
        top--;
        return s;
      }
    }

    string peek(){
      if(top < 0){
        cout << "Stack is empty";
        return "";
      }
      else{
        string s= stackArray[top];
        return s;
      }
    }

    bool isEmpty() {
      return(top < 0);
    }
};

bool isNumber(string s){
  if(s >= "0" && s <= "9"){
    return true;
  }
  else{
    return false;
  }
}

bool isOperator(string s){
  if(s == "+" || s == "-" || s == "*" || s == "/" || s == "^"){
    return true;
  }
  else{
    return false;
  }
}

bool isValidCharacter(string s){
  if(isNumber(s) || isOperator(s)){
    return true;
  }
  else if(s == "(" || s == ")"){
    return true;
  }
  else if(s == "{" || s == "}"){
    return true;
  }
  else if(s == "[" || s == "]"){
    return true;
  }
  else{
    return false;
  }
}

int precedence(string op){
  if(op == "^"){
    return 3;
  }
  else if(op == "*" || op == "/"){
    return 2;
  }
  else if(op == "+" || op == "-"){
    return 1;
  }
  else{
    return -1;
  }
}

bool isMatchingPair(string s1, string s2){
  if(s1 == "(" && s2 == ")"){
    return true;
  }
  else if(s1 == "{" && s2 == "}"){
    return true;
  }
  else if(s1 == "[" && s2 == "]"){
    return true;
  }
  else{
    return false;
  }
}

bool areParenthesesBalanced(string exp){
  Stack s;
  for(int i = 0; i < exp.size(); i++){
    if(exp[i] == '(' || exp[i] == '{' || exp[i] == '['){
      s.push(string(1, exp[i]));
    }
    if(exp[i] == ')' || exp[i] == '}' || exp[i] == ']'){
      if(s.isEmpty() || !isMatchingPair(s.pop(), string(1, exp[i]))){
        return false;
      }
    }
  }
  return s.isEmpty();
}

string to_postfix(string infix){
  Stack s;
  string postfix = "";
  if(!areParenthesesBalanced(infix)) {
    cout << "Error: Invalid parentheses" << endl;
    return "";
  }
  for (int i = 0; i < infix.size(); i++) {
    string infixString(1, infix[i]);
    if (infix[i] == ' '){
      cout << "Error: Invalid number of operators" << endl;
      return "";
    }
    if (isValidCharacter(infixString)){
      if (isNumber(infixString)) {
        postfix += infixString;
      }
      else if (infixString == "(" || infixString == "[" || infixString == "{") {
        s.push(infixString);
      }
      else if (infixString == ")" || infixString == "]" || infixString == "}") {
        while (!s.isEmpty() && s.peek() != "(" && s.peek() != "[" && s.peek() != "{") {
          postfix += s.pop();
        }
        if (s.isEmpty()) {
          cout << "Error: Invalid parentheses" << endl;
          return "";
        }
        else {
          s.pop();
        }
      }
      else {
        while (!s.isEmpty() && precedence(infixString) <= precedence(s.peek())) {
          postfix += s.pop();
        }
        s.push(infixString);
      }
    }
    else{
      cout << "Invalid character '" << infix[i] << "' in the expression" << endl;
      return "";
    }
  }
  while (!s.isEmpty()) {
    postfix += s.pop();
  }
  return postfix;
}

void print_postfix(string postfix){
  if(postfix != ""){
    cout << "Postfix expression: ";
    for(int i = 0; i < postfix.size(); i++){
      cout << postfix[i] << " ";
    }
    cout << endl;
  }
}

double evaluatePostfix(string postfix){
  Stack s;
  for(int i = 0; i < postfix.size(); i++){
    string postfixString(1, postfix[i]);
    if(isOperator(postfixString)){
      if(s.isEmpty()){
        cout << "Error: Invalid number of operands";
        return 0;
      }
      int op1 = stoi(s.pop());
      if(s.isEmpty()){
        cout << "Error: Invalid number of operands";
        return 0;
      }
      int op2 = stoi(s.pop());
      double result = 0.0;

      switch(postfix[i]){
        case '+':
          result = op2 + op1;
          break;
        case '-':
          result = op2 - op1;
          break;
        case '*':
          result = op2 * op1;
          break;
        case '/':
          if(op1 == 0){
            cout << "Error: Division by zero" << endl;
          }
          result = (double)op2 / op1;
          break;
        case '^':
          result = pow(op2, op1);
          break;
        case '%':
          result = fmod(op2, op1);
          break;
        default:
          cout << "Error: Invalid operator" << endl;
      }
      s.push(to_string(result)); 
    }
    else{
      s.push(postfixString);
    }
  }
  if(!s.isEmpty()) {
    string resultString = s.pop();
    if(!resultString.empty() && isNumber(resultString)){
      return stod(resultString);
    }
  }
  return 0;
}

int main() {
  string infixExpression;
  cout << "Enter an infix expression: ";
  getline(cin, infixExpression);

  string postfixExp = to_postfix(infixExpression);

  print_postfix(postfixExp);

  double result = evaluatePostfix(postfixExp);
    if(result != 0.0){
      cout << "Result: " << fixed << setprecision(3) << result << endl;
    }
  
  return 0;
}
Posted

Create a global bool variable called AnErrorOccurred and set it to false.
When an error does occur, set it to true.
In your print method, check the variable. if it is false, print the expression.
Then in either case, set it to false again for next time.
 
Share this answer
 
v2
The function print_postfix() only outputs the string as required if it is not empty.

If the message "Error: invalid number of operands" is to be output if, for example, only "+" is entered, the to_postfix() function should recognize this and output it.

Currently the function to_postfix() does not recognize such errors and print_postfix() outputs the "+". In such cases, both the error message should be output and the result string should also be empty.

Improvements for to_postfix()
- Remove spaces in advance instead of interpreting them as errors
- With valid infix notation, a number or an open bracket should be at the beginning.
->Currently this is not checked and a single "+" ends up on the stack.
- If an invalid character occurs, there is always an immediate error
- The sequence and priority of operands and numbers must be checked

The function to_postfix() seems to have many shortcomings. I therefore suggest improving the function.

You can look at this to convert infix notation:
https://en.wikipedia.org/wiki/Shunting_yard_algorithm
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900