Application of stacks: analytic arithmetic expressions

Source: Internet
Author: User
Tags arithmetic bool

Original blog: http://blog.csdn.net/zhangxiangDavaid/article/details/27176751

Similar to the 1*2-3+4-(5-6)-2/4 equation, we call it an arithmetic expression. Here we use the data structure of the stack to parse it, that is, to use the stack to help calculate the arithmetic expression.
First we have to make a clear calculation of the rules:
First left and right: counting from left to right
Multiplication first, then add and subtract
In parentheses, outside the brackets
Principle:
Use two stacks to store read-in characters: digital stacks and symbol stacks
Reads the number, then presses into the digital stack
When reading the symbol, the symbol at the top of the current symbol stack is compared to the symbol that is being read into. If the top symbol of the current symbol stack has a small priority, continue to press the symbol into the symbol stack; If the current read-in symbol has a small priority, the number stack sequentially stacks two numbers, plus the symbol stack top symbol, constitutes an arithmetic expression, through the calculation results, the results are pressed into the digital stack.
When reading the bounds or symbol stack popup bounds, such as #, the end of the operation, the stack of numbers, that is, the last expression value.
Difficulties:
1, Priority series group priorities understanding is difficult.
+ - * / ( ) #
+ 1 1 2 2 2 1 1
-1 1 2 2 2 1 1
* 1 1 1 1 2 1 1
/1 1 1 1 2 1 1
(2 2 2 2 2 3 0
) 1 1 1 1 0 1 1
#2 2 2 2 2 0 3

Each location can be represented by (I,J), where I is a row and J is a column. One thing to be clear: the symbol I is preceded by the symbol J. That is, the symbol I is on the left side of the symbol J in an arithmetic expression. 1:>,2:<,3:=. The precedence of the boundary symbol # is the lowest. Here are some examples:
(+,+) = 1, two ' + ' are siblings, but the first one precedes the second and is known:> by the above calculation Rule 1.
((, #) = 0, if the opening parenthesis ' (' appears, at least the closing parenthesis ') ' appears, there will be a boundary break, otherwise an error occurs.
(), () = 0, we do not support (...) (...) In this notation, there must be at least another operator between the two parentheses, such as (...). *(...)。
(#,)) = 0, did not encounter the opening parenthesis ' (', how to appear the closing parenthesis ') ', so error.
2, when the symbol at the top of the stack is higher than the current read operator, the number stack out of the first number as the second operand, the next number of the stack as the first operand, it is clear. Operand: operand operator: operator
details see code:

#include <iostream> #include <stack> using namespace std;  Char op[7] = {' + ', '-', ' * ', '/', ' (', ') ', ' # '}; operator set int priority[7][7] =//When operators meet, priority comparison 1: Greater Than, 2: less Than, 3: equals, 0: not possible, error {{1, 1, 2, 2, 2, 1, 1}, {1, 1  , 2, 2, 2, 1, 1}, {1, 1, 1, 1, 2, 1, 1}, {1, 1, 1, 1, 2, 1, 1}, {2, 2, 2, 2, 2, 3, 0}, {1,  
1, 1, 1, 0, 1, 1}, {2, 2, 2, 2, 2, 0, 3}};  
            BOOL Isopat (char c)//is the operator in op[] {for (int i = 0; i < 7; i++) {if (c = = Op[i])  
    return true;  
} return false;  
    } int getpriority (char C1,char C2)//comparison priority {int I, J;  
        for (int r = 0; r < 7; r++) {if (C1 = = Op[r]) i = r;  
    if (C2 = = Op[r]) j = r;  
} return PRIORITY[I][J]; } int Compute (char A, char op, char b) {switch (OP) {case ' + ': return (A-' 0 ') + (b-')  
    0 '); Case '-': return (A-' 0 ')-(b-' 0 ');  
    Case ' * ': return (A-' 0 ') * (b-' 0 '); Case '/': if (b = = ' 0 ') {cout << "error.  
            "<< Endl;  
        Exit (0);  
    } return (A-' 0 ')/(b-' 0 ');    }} void EvaluateExpression ()//calculation {stack<char> opan,opat;    Build two stacks of operand: operands, Operator: operator Opat.push (' # ');  
    # Press the symbol stack as the cout << "input arithmetic expression" << endl;  
    Char op,a,b,c;  
    C=getchar ();  
        while (c! = ' # ' | | opat.top ()! = ' # ')//does not read ' # ' or the symbol stack is not available, continue reading the character {//To determine whether the characters are read: operand or operator.  
            if (!isopat (c))//is the operand is pressed into the operand stack {opan.push (c);  
        c = GetChar ();  
            } else//If operator, the operator with the top of the symbol stack should be compared with the current read-in operator to prioritize {switch (getpriority (Opat.top (), C))  
                {Case 1:op = Opat.top (); Opat.pop (); b = Opan.top ();  
                Opan.pop (); A = Opan.top ();  
                Opan.pop ();  
                Opan.push (char (COMPUTE (a,op,b) + ' 0 '));  
            Break  
                Case 2:opat.push (c);  
                c = GetChar ();  
            Break  
                Case 3:opat.pop ();  
                c = GetChar ();  
            Break Case 0:cout << "error.  
                "<< Endl;  
            Exit (0);  
}}} cout << "=" << opan.top ()-' 0 ' << Endl;  
    } int main () {cout << "use stack structure to parse calculation expression" <<endl;  
    EvaluateExpression ();  
    System ("pause");  
return 0;   }

Description: You can use the implementation of the stack: the code in the sequential stack, but here for convenience, reduce the amount of code, using # include, in fact, the effect is the same. The above procedure, just completed a simple operation. It's simple because you can only enter a number of 0-9, and you can't handle an expression that starts with a symbol, such as -3*4,+2-5, and then an error occurs. Subsequent supplemental enhancements that can handle operations such as 34+34, multi-digit arithmetic.

Update 2014-5-28 00:28

This update resolves the above issues and adds the seek remainder operator. The code is as follows:

#include <iostream> #include <stack> using namespace std;  Char Op[8] = {' + ', '-', ' * ', '/', '% ', ' (', ') ', ' # '}; operator set int priority[8][8] =//each operator encounters a priority comparison of 1: Greater Than, 2: less Than, 3: equals, 0: not possible, error {{1, 1, 2, 2, 2, 2, 1, 1}, {1, 1, 2, 2, 2, 2, 1, 1}, {1, 1, 1, 1, 1, 2, 1, 1}, {1, 1, 1, 1, 1, 2, 1, 1}, {1, 1, 1, 1, 1, 2, 1, 1  
}, {2, 2, 2, 2, 2, 2, 3, 0}, {1, 1, 1, 1, 1, 0, 1, 1}, {2, 2, 2, 2, 2, 2, 0, 3}};  
            BOOL Isopat (char c)//is the operator in op[] {for (int i = 0; i < 8; i++) {if (c = = Op[i])  
    return true;  
} return false;  
    } int getpriority (char C1,char C2)//comparison priority {int I, J;  
        for (int r = 0; r < 8; r++) {if (C1 = = Op[r]) i = r;  
    if (C2 = = Op[r]) j = r;  
} return PRIORITY[I][J]; } int compute (int A, char op, int b) {switch (OP) {case ' + ': return a + b;  
    Case '-': return a-B;  
    Case ' * ': return a*b; Case '/': Case '% ': if (b = = 0) {cout << "error.  
            "<< Endl;  
        Exit (0);  
        } if (op = = '/') return a/b;  

    else return a%b;     }} void EvaluateExpression ()//calculation {stack<int> Opan;    operand stack stack<char> opat;    Operation Fu Yi Opat.push (' # ');  
    # Press the symbol stack as the cout << "input arithmetic expression" << endl;    Char OP,C,CN;  
    Cn:char Next Next character int a,b,data;  
    C=getchar ();  
    if (Isopat (c))//If the first character is an operator, press 0 into the digital stack opan.push (0);  
        while (c! = ' # ' | | opat.top ()! = ' # ')//does not read ' # ' or the symbol stack is not available, continue reading the character {//To determine whether the characters are read: operand or operator.  
            if (!isopat (c))//is the operand is pressed into the operand stack {data = c-' 0 '; while (!isopat (cn = GetChar ()))//Next word Fuzhin as number {data = data* Ten + CN-' 0 ';  
            } opan.push (data);   C = cn; To assigned the operation in CN to the C} else//If operator, the operator with the top of the symbol stack should be compared with the current read-in operator, with the precedence of the {switch (Getpriori  
                Ty (Opat.top (), c)) {Case 1:op = Opat.top (); Opat.pop (); b = Opan.top ();  
                Opan.pop (); A = Opan.top ();  
                Opan.pop ();  
                Opan.push (Compute (A,OP,B));  
            Break  
                Case 2:opat.push (c);  
                c = GetChar ();  
            Break  
                Case 3:opat.pop ();  
                c = GetChar ();  
            Break Case 0:cout << "error.  
                "<< Endl;  
            Exit (0);  
}}} cout << "=" << opan.top () << Endl;  
    } int main () {cout << "use stack structure to parse calculation expression" <<endl;  
    EvaluateExpression ();System ("pause");  
return 0;   }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.