-2

I am trying to write a C++ program to convert infix expressions to prefix and postfix. Where did I go wrong?

How can I change code to delete parentheses at the last form (postfix)? Thanks for any help!

Input :

a*(b-c+d)/e

Output :

abc-d+*e/
/*a+-bcde

Constraints/Assumptions :

  1. Expression is balanced.
  2. The only operators used are +, -, *, /
  3. Opening and closing brackets - ( ) - are used to impact precedence of operations.
  4. + and - have equal precedence which is less than * and /. * and / also have equal precedence.
  5. In two operators of equal precedence give preference to the one on left.
  6. All operands are single-digit numbers/characters.
#include <cstring>
#include <ctype.h>
#include <iostream>
#include <stack>
#include <string>
using namespace std;

int precedence(char ch) {
    if (ch == '+') {
        return (1);
    } else if (ch == '-') {
        return (1);
    } else {
        return (2);
    }
}

void preProcess(stack<string> &preS, char op) {
    string val2 = preS.top();
    preS.pop();
    string val1 = preS.top();
    preS.pop();
    string prev;
    prev = op + val1 + val2;
    preS.push(prev);
}

void postProcess(stack<string> &postS, char op) {
    string val2 = postS.top();
    postS.pop();
    string val1 = postS.top();
    postS.pop();
    string postv;
    postv = val1 + val2 + op;
    postS.push(postv);
}

void prefixPostfixEvaluation(string expr) {
    stack<string> preS;
    stack<string> postS;
    stack<char> opS;
    for (int i = 0; i < expr.length(); ++i) {
        char ch = expr.at(i);
        if (ch == '(') {
            opS.push(ch);
        } else if ((ch <= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') ||
                   (ch <= 'A' && ch >= 'Z')) {
            string s;
            s = ch;
            preS.push(s);
            postS.push(s);
        } else if (ch == ')') {
            while (opS.top() != '(') {
                char op = opS.top();

                preProcess(preS, op);
                postProcess(postS, op);
                opS.pop();
            }
            opS.pop();
        } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
            while (opS.size() > 0 && precedence(ch) <= precedence(opS.top()) &&
                   opS.top() != '(') {
                char op = opS.top();

                preProcess(preS, op);
                postProcess(postS, op);
                opS.pop();
            }
            opS.push(ch);
        }
    }
    while (opS.size() > 0) {
        char op = opS.top();
        opS.pop();
        if (op == '(' || op == ')') {
            continue;
        } else {
            preProcess(preS, op);
            postProcess(postS, op);
        }
    }
    cout << preS.top() << endl;
    cout << postS.top();
}

int main() {
    string expr;
    getline(cin, expr);
    prefixPostfixEvaluation(expr);
}
brc-dd
  • 10,788
  • 3
  • 47
  • 67
Kushagra
  • 3
  • 4
  • At first grance, the condition `(ch<='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch<='A'&&ch>='Z')` looks weird, especiallyi the first and last pairs compounded by `()`. – MikeCAT Sep 04 '20 at 15:59
  • 5
    How artistic your indentation is! – MikeCAT Sep 04 '20 at 16:00
  • can you elaborate – Kushagra Sep 04 '20 at 16:00
  • 1
    `(ch<='0'&&ch<='9')` is equivalent to `ch<='0'`. `(ch<='A'&&ch>='Z')` will never become true if `'A'` is smaller than `'Z'`. – MikeCAT Sep 04 '20 at 16:01
  • 2
    It sounds like you may need to learn how to use a debugger to step through your code. With a good debugger, you can execute your program line by line and see where it is deviating from what you expect. This is an essential tool if you are going to do any programming. Further reading: [How to debug small programs](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) and [Debugging Guide](http://idownvotedbecau.se/nodebugging/) – NathanOliver Sep 04 '20 at 16:02
  • Seriously, your indentation alone makes the code harder to debug. [See this version of the same code](http://coliru.stacked-crooked.com/a/d3ee2e5f1b4aec18) – PaulMcKenzie Sep 04 '20 at 16:32

1 Answers1

1

Your condition to check if a character is an operand is wrong. Instead of :

(ch <= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch <= 'A' && ch >= 'Z')

It should be

(ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')

A better way would be to directly use isalnum(ch) in the conditional statement (you have already included ctype header).

Complete (corrected) code can be found here.

Note : Prefer including C++ variants of header like <cctype> instead of <ctype.h>. Moreover, there is no need to include <cstring> when <string> is included. Also, please go through this thread : Why is “using namespace std;” considered bad practice?

You are expecting postfix version to appear on line 1 and the prefix version to appear on line 2. But in code you're printing in reverse order, change it if order matters to you.

brc-dd
  • 10,788
  • 3
  • 47
  • 67