nyoj35 - Reverse Polish Expression

Reverse Polish expressions, also known as postfix expressions, are used in the programming of the four mixed operations.

E.g:

1+2 written as a postfix expression is 12+

The postfix expression of 4+5*(3-2) is 4532-*+

The postfix expression brings unexpected convenience in the four arithmetic operations, and the priority is automatically maintained during the generation process;

The algorithm for generating the Reverse Polish expression is as follows:

We first use two stack structures to store operators and operands;

From doing right iterate over our input infix expression:

1. If it is an operand, then directly push it into the stack where the operand is stored;

2. If it is a "(" left parenthesis, then it is directly pushed into the stack where the operator is stored;

3. If it is a ")" right parenthesis, then pop the data from the operator stack and push the popped data into the operand stack until it encounters "(". It is worth noting here that "( "It must be popped from the operator stack, but not pushed onto the operand stack, and the postfix expression does not contain parentheses;

4. If it is other symbols, it is other operators +-*/ these, then:

  a. If the operator stack is empty, push it directly into the operator stack;

  b. If it is not empty and the top element of the operator stack is parentheses, including left and right parentheses, it is also directly pushed into the operator stack;

  c. If the priority of the element traversed at this time is higher than the priority of the top element of the operator stack at this time, it is directly pushed into the operator stack;

  d. If the priority of the element being traversed is equal to or less than the priority of the element at the top of the operator stack, the top element of the stack needs to be popped and placed on the operand stack, and the element being traversed is pushed into the Operator stack, in fact, the order of elements in the operator stack is the order of priority;

5. Until the expression is traversed, all elements in the operator stack need to be pushed into the operand stack, and the algorithm is completed.

 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

According to the above algorithm, the Reverse Polish expression can be obtained. After we obtain the Reverse Polish expression, we must obtain the correct calculation result. With the Reverse Polish expression, the calculation is much more complicated. The algorithm is as follows:

Using another stack to hold the data, traverse the reverse Polish expression from left to right:

1. If it is a number, it is directly pushed into the stack;

2. If it is an operator (+,-,*,/), pop the two data in the stack, perform the corresponding calculation, get a data after the calculation is completed, and then push it into the stack;

3. Until the traversal is completed, the data in the stack is the result of the final calculation, simple

The above is taken from: https://blog.csdn.net/uestclr/article/details/50630906

AC code:

#include <bits/stdc++.h>
using namespace std;

int prio( char x)   // define precedence 
{
     switch (x){
         case  ' + ' : return  1 ;
         case  ' - ' : return  1 ;
         case  ' * ' : return  2 ;
         case  ' / ' : return  2 ;
         default : return  0 ; // Parens will appear by default, and if there are parentheses, they must be pressed in 
    }
}




intmain ()
{
    int t;
    cin >> t;
    while(t--){
        stack<char>s;
        stack<double>d;
        string s1,s2;
        cin >> s1;
        int i=0;
        s2 = "";
        s.push( ' # ' );
         while (i < s1.length()- 1 ){ // The equal sign does not need to scan 
            if ( ' ( ' == s1[i]){
                s.push(s1[i++]);
            }
            else if(')' == s1[i]){
                while(s.top() != '('){
                    s2 += s.top();
                    s2 += '  ' ; // Adding spaces is for the convenience of calculation 
                    s.pop();
                }
                s.pop(); // pop the left parenthesis 
                i++ ;
            }
            else if(s1[i] == '+'||s1[i] == '-'||s1[i] == '*'||s1[i] == '/'){
                while(prio(s.top()) >= prio(s1[i])){
                    s2 += s.top();
                    s2 += ' ';
                    s.pop();
                }
                s.push(s1[i]);
                i++;
            }
            else { // If it is a number class 
                while (s1[i] >= ' 0 ' &&s1[i] <= ' 9 ' ||s1[i] == ' . ' ){
                    s2 += s1[i++];
                }
                s2 += ' ';
            }
        }
        while (s.top() != ' # ' ){ // When the expression is scanned, there are remaining symbols in the stack 
            s2 += s.top();
            s2 += ' ';
            s.pop();
        }

//        cout << s2 << endl;

        double result = 0;
        i = 0;
        while(i < s2.length()){
            switch (s2[i]){
                case '+':
                    result = d.top();
                    d.pop();
                    result += d.top();
                    d.pop();
                    i++;
                    break;
                case '-':
                    result = d.top();
                    d.pop();
                    result = d.top() - result;
                    d.pop();
                    i++;
                    break;
                case '*':
                    result = d.top();
                    d.pop();
                    result *= d.top();
                    d.pop();
                    i++;
                    break;
                case '/':
                    result = d.top();
                    d.pop();
                    result = d.top()/result; // Note that because it is a stack, the order of division changes 
                    d.pop();
                    i++;
                    break;
                default:
                    result = 0;
                    double fac = 10.0;
                    while(s2[i] >= '0'&&s2[i] <= '9'){
                        result = result*10 + s2[i] - '0';
                        i++;
                    }
                    if(s2[i++] == '.'){
                        while(s2[i] >= '0'&&s2[i] <= '9'){
                            result += (s2[i] - '0')/fac;
                            fac * = 10 ;
                            i++;
                        }
                    }
            }
//            cout << result << endl;
            d.push(result);
            while(s2[i] == ' '){
                i++;
            }
        }
        printf("%.2lf\n",d.top());
    }
    return 0;
}

 ——

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324779664&siteId=291194637