Parsing String of symbols to Expression - GeeksforGeeks

13 Aug, 2021
Given an expression as a string str consisting of numbers and basic arithmetic operators(+, -, *, /), the task is to solve the expression. Note that the numbers used in this program are single-digit numbers and parentheses are not allowed.Examples:  
Input: str = “3/3+4*6-9” Output: 16 Since (3 / 3) = 1 and (4 * 6) = 24. So the overall expression becomes (1 + 24 – 9) = 16Input: str = “9*5-4*5+9” Output: 16  
 
Approach: A Stack class is created to store both numbers and operators (both as characters). The stack is a useful storage mechanism because, when parsing expressions, the last item stored needs to be accessed frequently; and a stack is a last-in-first-out (LIFO) container.Besides the Stack class, a class called express(short for expression) is also created, representing an entire arithmetic expression. Member functions for this class allow the user to initialize an object with an expression in the form of a string, parse the expression, and return the resulting arithmetic value.Here’s how an arithmetic expression is parsed. A pointer is started at the left and is iterated to look at each character. It can be either a number(always a single-digit character between 0 and 9) or an operator (the characters +, -, *, and /).If the character is a number, it is pushed onto the stack. The first operator encountered is also pushed into the stack. The trick is subsequent operators are handled. Note that the current operator can’t be executed because the number that follows it hasn’t been read yet. Finding an operator is merely the signal that we can execute the previous operator, which is stored on the stack. That is, if the sequence 2+3 is on the stack, we wait until we find another operator before carrying out the addition.Thus, whenever the current character is an operator (except the first), the previous number (3 in the preceding example) and the previous operator (+) are popped off the stack, placing them in the variables lastval and lastop. Finally, the first number (2) is popped and the arithmetic operation is carried on the two numbers (obtaining 5). However, when * and / which have higher precedence than + and – are encountered, the expression can’t be executed. In the expression 3+4/2, the + cant be executed until the division is performed. So, the 2 and the + are put back on the stack until the division is carried out.On the other hand, if the current operator is a + or -, the previous operator can be executed. That is when the + is encountered in the expression 4-5+6, it’s all right to execute the -, and when the – is encountered in 6/2-3, it’s okay to do the division. Table 10.1 shows the four possibilities. 
 
Below is the implementation of the above approach: 
CPP
// C++ implementation of the approach#include <cstring>#include <iostream>using namespace std; // Length of expressions in charactersconst int LEN = 80; // Size of the stackconst int MAX = 40; class Stack {private:    // Stack: array of characters    char st[MAX];     // Number at top of the stack    int top; public:    Stack()    {        top = 0;    }     // Function to put a character in stack    void push(char var)    {        st[++top] = var;    }     // Function to return a character off stack    char pop()    {        return st[top--];    }     // Function to get the top of the stack    int gettop()    {        return top;    }}; // Expression classclass Express {private:    // Stack for analysis    Stack s;     // Pointer to input string    char* pStr;     // Length of the input string    int len; public:    Express(char* ptr)    {        pStr = ptr;        len = strlen(pStr);    }     // Parse the input string    void parse();     // Evaluate the stack    int solve();}; void Express::parse(){     // Character from the input string    char ch;     // Last value    char lastval;     // Last operator    char lastop;     // For each input character    for (int j = 0; j < len; j++) {        ch = pStr[j];         // If it's a digit then save        // the numerical value        if (ch >= '0' && ch <= '9')            s.push(ch - '0');         // If it's an operator        else if (ch == '+' || ch == '-'                 || ch == '*' || ch == '/') {             // If it is the first operator            // then put it in the stack            if (s.gettop() == 1)                 s.push(ch);             // Not the first operator            else {                lastval = s.pop();                lastop = s.pop();                 // If it is either '*' or '/' and the                // last operator was either '+' or '-'                if ((ch == '*' || ch == '/')                    && (lastop == '+' || lastop == '-')) {                     // Restore the last two pops                    s.push(lastop);                    s.push(lastval);                }                 // In all the other cases                else {                     // Perform the last operation                    switch (lastop) {                     // Push the result in the stack                    case '+':                        s.push(s.pop() + lastval);                        break;                    case '-':                        s.push(s.pop() - lastval);                        break;                    case '*':                        s.push(s.pop() * lastval);                        break;                    case '/':                        s.push(s.pop() / lastval);                        break;                    default:                        cout << "\nUnknown oper";                        exit(1);                    }                }                s.push(ch);            }        }        else {            cout << "\nUnknown input character";            exit(1);        }    }} int Express::solve(){    // Remove the items from stack    char lastval;    while (s.gettop() > 1) {        lastval = s.pop();        switch (s.pop()) {         // Perform operation, push answer        case '+':            s.push(s.pop() + lastval);            break;        case '-':            s.push(s.pop() - lastval);            break;        case '*':            s.push(s.pop() * lastval);            break;        case '/':            s.push(s.pop() / lastval);            break;        default:            cout << "\nUnknown operator";            exit(1);        }    }    return int(s.pop());} // Driver codeint main(){     char string[LEN] = "2+3*4/3-2";     // Make expression    Express* eptr = new Express(string);     // Parse it    eptr->parse();     // Solve the expression    cout << eptr->solve();     return 0;}
4
 
Time Complexity: O(N).Auxiliary Space: O(N). 
pankajsharmagfg
Data Structures
Stack
Strings
Data Structures
Strings
Stack
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Start Learning DSA?
Introduction to Tree Data Structure
Program to implement Singly Linked List in C++ using class
Hash Functions and list/types of Hash functions
Insertion in a B+ tree
Stack Data Structure (Introduction and Program)
Stack Class in Java
Stack in Python
Check for Balanced Brackets in an expression (well-formedness) using Stack
Stack | Set 2 (Infix to Postfix)