Solving arithmetic expressions using stacks

Source: Internet
Author: User
Tags stack pop

1. Objectives of this Article

Analyze the basic method for parsing arithmetic expressions using stacks. The sample code can be used to parse any arithmetic expressions that consist of +,-, *,/, (), and numbers 0 to 9.

2. infix expression and suffix expression

An infix expression is generally called an arithmetic expression, such as (1 + 2) * 3-4.

A suffix expression is an expression after the number of operations of an operator after resolution. For example, a suffix expression is resolved as 12 + 3*4 -. This expression can be solved directly using stacks.

3 operator priority

Priority Operator
1 Parentheses ()
2 Minus sign-
3 Multiplication party **
4 Multiplication *, Division/, returns the remainder %
5 Add +, minus-
6 Less than <, less than or equal to <=, greater than>, greater than or equal to> =
7 Equal to =, not equal! =
8 Logic &&
9 Logic or |


The general rule is that unary operators> binary operators> multivariate operators.

4. Process of parsing arithmetic expressions using stacks

The method for translating an infix expression into a suffix expression is as follows:

(1) obtain data ch from left to right.

(2) If ch is the operand, It is output directly.

(3) If ch is an operator (including parentheses), then:
A: If CH = '(', put it into the stack.
B: If CH = ')', the operators in the stack are output until '(' is encountered.
C: If ch is not ')' or '(', the priority is compared with the top operator of the stack vertex position.
1: If CH has a higher priority than top, place CH in the stack.
2: If the CH priority is lower than or equal to top, output top and put ch into the stack.

(4) If the expression has been read, and there are operators in the stack, output from the top one in turn.

If we have an expression (A-B) * C + D-E/F, to translate it into a suffix expression and store the suffix expression in a string named output, you can use the following steps.

(1) read '(', pushed to the stack, and output is empty
(2) read A, which is the number of operations and is directly output to the output string. Output =
(3) read '-'. At this time, there is only one '(' in the stack, so press '-' into the stack, output =
(4) read B, which is the number of operations and is directly output to the output string. Output = AB
(5) read ')'. At this time, the operator '-' in the stack is output in sequence, and then '(' is displayed directly, output = AB-
(6) read '*', which is an operator. Because the stack is empty at this time, it is directly pushed into the stack. Output = AB-
(7) read C, is the number of operations, directly output to the output string, output = AB-C
(8) read '+', is the operator, its priority is lower than '*', then pop up '*', press '+ ", output = AB-C *
(9) read D, is the number of operations, directly output to the output string, output = AB-C * d
(10) read '-', is operator, and '+' priority is the same, so pop-up '+', then press '-', output = AB-C * D +
(11) read e is the number of operations, directly output to the output string, output = AB-C * D + E
(12) read '/', is an operator, higher than the '-' priority, so pressed into the stack, output = AB-C * D + E
(13) read f, is the number of operations, directly output to the output string, output = AB-C * D + ef
(14) The original string has been read, the remaining operators in the stack pop up in turn, output = AB-C * D + EF /-

5. Calculate the arithmetic expression

When a suffix expression is available, it is very easy to calculate the value of the expression. It can be calculated according to the following process.

(1) scan the expression from left to right and extract a data
(2) If data is an operand, It is pushed into the stack.
(3) If data is an operator, the number of data required by this operator is displayed in the stack for calculation, and the result is pushed to the stack.
(4) If the data processing is complete, the last remaining data in the stack is the final result.

For example, to process a suffix expression 1234 + * + 65/-, follow these steps.

(1) first, 1, 2, 3, 4 are all operands, and all of them are pushed into the stack.
(2) Obtain '+', which is an operator. Data 3, 4 is displayed. Expected result 7 is displayed. Then, 7 is pushed to the stack.
(3) Obtain '*', as the operator, pop up data, get data 14, and then press 14 into the stack.
(4) Obtain '+', which is an operator. Data is displayed, result 15 is displayed, and 15 is pushed to the stack.
(5) both 6 and 5 are data and all are pushed into the stack.
(6) Obtain '/', which is an operator. Data 6 and 5 are displayed. The result 1.2 is displayed. Then, 1.2 is pushed to the stack.

(7) Get '-', which is an operator. The data 15, 1.2 is displayed, and the data 13.8 is obtained. This is the final calculation result.

The following code is used to convert an infix expression into a suffix expression.

/*************************************** * ******************************** // * Description: use the stack to change \ * infix expression into Postfix expression. * Author: gecko * Date: 2012-12-25 10:59 * Note: /*************************************** * *******************************/# include "iostream "# include "string" # include <windows. h> using namespace STD; int op [50]; int P =-1; void processstring (stri Ng Str) {int Len = Str. length (); int op_nxt = 0; int flag = 0; For (INT I = 0; I <Len; I ++) {// If the operand is if (STR [I]> = 'A' & STR [I] <= 'Z ') | (STR [I] >='0' & STR [I] <= '9') {cout <STR [I];} // If the operator else if (STR [I]! = '') {Switch (STR [I]) {Case '+': op_nxt = 0; break; Case '-': op_nxt = 1; break; Case '*': op_nxt = 2; break; Case '/': op_nxt = 3; break; Case '^': op_nxt = 4; break; Case '(': op_nxt = 5; break; case ')': op_nxt = 6; break;} // if it is '(', press the operator into if (op_nxt = 5) {op [++ p] = op_nxt; flag = 1 ;}// if it is ')', the operator pops up until '(' until else if (op_nxt = 6) {While (OP [p]! = 5) {Switch (OP [p]) {Case 0: cout <'+'; break; Case 1: cout <'-'; break; Case 2: cout <"*"; break; Case 3: cout <'/'; break; Case 4: cout <'^'; break;} p --;} flag = 0; p --;} // If the operator priority is higher than the stack top operator, press else if (P =-1 | op_nxt> op [p] | flag = 1) OP [++ p] = op_nxt; else // If the operator priority is less than or equal to the top of the stack operator, {While (P> = 0 & op_nxt/2 <= op [p]/2) is displayed) {Switch (OP [p]) {Case 0: cout <'+'; break; Case 1: cout <'-'; break; Case 2: cout <"*"; break; Case 3: cout <'/'; break; Case 4: cout <'^'; break;} p --;} OP [++ p] = op_nxt ;}}while (P >=0) {Switch (OP [p]) {Case 0: cout <'+'; break; case 1: cout <'-'; break; Case 2: cout <"*"; break; Case 3: cout <'/'; break; Case 4: cout <'^'; break;} p --;} cout <Endl;} int main () {// string STR = "(1 + 2) * 3-4 "; // string STR =" 1 + 2*3 "; // string STR =" (1 + 2) * 3 "; string STR = "A + B * (C + D)-E/F"; processstring (STR); System ("pause"); Return 0 ;}

The above code encountered some problems during the writing process:

1. if '(' exists in the symbol stack, this is to add the operator that is encountered to the stack directly. How can we determine if '(' is already in the stack, we have added a flag identifier for difference.

2. in the process of setting the symbol priority, we set different levels for each operator for the convenience of subsequent operations, but in actual operations, '+' and '-'; '*' and '/' have the same priority. Note that when the priority is smaller than or equal to the priority of the stack top operator, the top element of the stack needs to be pushed in. '+' (0) and '-' (1). How can this problem be determined? TIPS: Use the Division 2 method.

3. when ')' is encountered, the operator needs to be popped up until ')' is encountered. At the end of the loop, the top element of the stack '(' is not popped up, so after jumping out of the loop, p -- again, but no p -- the program can still get the correct result because '(' and ') is not input '). The most important step in a loop is to set the flag to 1.

/*************************************** * ******************************** // * Description: calculate the equation. * Author: gecko * Date: 2012-12-25 10:59 * Note: /*************************************** * *******************************/# include "iostream "# include "string" # include <windows. h> using namespace STD; int num [50], OP [50]; int P =-1, q =-1; int pow_int (int A, int B) {int K = 1; for (INT I = 0; I <B; I ++) K * = A; return K;} void cul (INT P, int OP) {If (OP = 0) num [P-1] = num [P-1] + num [p]; If (OP = 1) num [P-1] = num [P-1]-num [p]; if (OP = 2) num [P-1] = num [P-1] * num [p]; If (OP = 3) num [P-1] = num [P-1]/num [p]; If (OP = 5) num [P-1] = pow_int (Num [P-1], num [p]);} int processstring (string Str) {int Len = Str. length (); int op_nxt = 0; int num_nxt = 0; int flag = 0; int change = 0; For (int I = 0; I <Len; I ++) {// If the operand is if (STR [I]> = '0' & STR [I] <= '9 ') {num_nxt = num_nxt * 10 + STR [I]-'0'; change = 1 ;}// if the operator is else if (STR [I]! = '') {If (change = 1) {num [++ q] = num_nxt; num_nxt = 0; change = 0;} switch (STR [I]) {Case '+': op_nxt = 0; break; Case '-': op_nxt = 1; break; Case '*': op_nxt = 2; break; Case '/': op_nxt = 3; break; Case '^': op_nxt = 4; break; Case '(': op_nxt = 5; break; Case ')': op_nxt = 6; break ;} // if it is '(', directly press the operator into if (op_nxt = 5) {op [++ p] = op_nxt; // flag = 1 ;} // if it is ')', the operator will pop up until '(' until else if (op_nxt = 6) {While (OP [p]! = 5) {cul (Q --, OP [p]); p --;} flag = 0; p --;} // If the operator has a higher priority than the stack top operator, directly Press/* else if (P =-1 | op_nxt> op [p] | flag = 1) OP [++ p] = op_nxt; */else // If the operator priority is less than or equal to the top of the stack operator, {While (P> = 0 & OP [p] <= 4 & op_nxt/2 <= op [p]/2) {cul (Q --, OP [p]); p --;} op [+ + P] = op_nxt ;}}while (P> = 0) {If (change = 1) {num [++ q] = num_nxt; num_nxt = 0; change = 0;} cul (Q --, OP [p]); p --;} return num [0];} int main () {// string STR = "(1 + 2) * 3-4 "; // string STR = "1 + 2*3"; // string STR = "(1 + 2) * 3/2 "; string STR = "12*(0 + 0*5)"; cout <processstring (STR) <Endl; System ("pause"); Return 0 ;}

Note:

1. merge "if the operator priority is higher than the top-stack operator, press it directly" with "if the operator priority is less than or equal to the top-stack operator, bring up", first judge and then press it directly.

2. Extract the numbers in the string, and extract 12, instead of 1 and 2, and distinguish the cases that contain 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.