Typical application of "stack"-expression evaluation (implemented in C language)

Source: Internet
Author: User
Tags stack pop

Expression evaluation is a basic problem in programming language compilation. Its implementation is a typical application of "stack. This article uses the simplest and most intuitive algorithm "operator Priority Method" to evaluate expressions ".

We all know that the four Arithmetic Operations follow the following rules:

Multiply, divide, and add or subtract.

From left to right

Calculate the value inside the brackets before calculating the value outside the brackets.

Expression Composition

Any expression consists of operands, operators, and delimiters.

The operands can be constants or identifiers described as variables or constants.

Operators can be divided into arithmetic operations, relational operations, and logical operators.

The delimiters include parentheses and terminator.

This document only uses arithmetic operations for convenience.

Operator priority

There are three relationships between the successive operators θ 1 and θ 2: greater than, equal to, and less. The priority between "+-*/" can be listed. See the following table:

  + - * / ( ) #
+ > > < < < > >
- > > < < < > >
* > > > > < > >
/ > > > > < > >
( < < < < < =  
) > > > >   > >
# < < < < <   =

 

The priority of addition, subtraction, multiplication, division, and division is lower than "(" but higher than ")". We can see from left to right that when θ 1 = θ 2, Let θ 1> θ 2

For the sake of concise algorithm, a "#" is set on the left and right sides of the expression. This "#" indicates that the evaluation of an expression is complete.

"(" = ")" When a pair of parentheses meet, it indicates that the calculation is completed in the brackets.

")", "(", "#", "(", "(" And "#" cannot appear successively. If yes, the expression syntax is incorrect.

To implement the priority algorithm, two working stacks, optr, and opnd, can be used to store the operation count and result.

Basic Idea of algorithms.

First, set the operand stack to an empty stack. The expression start character "#" is the base element of the stack.

Each character in the expression is read in sequence. If it is an operand, it is added to the opnd stack. If it is an operator, it is compared with the stack top operator of the optr stack for corresponding operations, until the entire expression is evaluated (both the top element of the optr stack and the currently read characters are "#")

Code implementation: first, familiarize yourself with Stack-related operations:
# Include "stdio. H "# include" malloc. H "# define true 1 # define false 0 # define OK 1 # define error 0 # define Infeasible-1 # define overflow-2 typedef int status; # define stack_init_size 100 # define stackincrement 10 typedef struct {selemtype * base; selemtype * Top; int stacksize;} sqstack; // construct an empty stack status initstack (sqstack * s) {S-> base = (selemtype *) malloc (stack_init_size * sizeof (selemtype); If (! S-> base) Exit (overflow); s-> Top = s-> base; s-> stacksize = stack_init_size; Return OK ;} // determine whether the stack status stackempty (sqstack s) {If (S. top = S. base) return true; else return false;} // use e to return the top element of S. Status gettop (sqstack S, selemtype * E) {If (S. top = S. base) Return Error; * E = * (S. top-1); Return OK;} // insert e as the new top element status push (sqstack * s, selemtype E) {If (S-> top-S-> base)> = s-> stacksize) {S-> base = (selemtype *) rea Lloc (S-> base, (S-> stacksize + stackincrement) * sizeof (selemtype); If (! S-> base) Exit (overflow); s-> Top = s-> base + S-> stacksize; s-> stacksize + = stackincrement ;} * (S-> top) = E; s-> top ++; Return OK;} // Delete the top element of S, use E to return its value status POP (sqstack * s, selemtype * E) {If (S-> Top = s-> base) Return Error; s-> top --; * E = * (S-> top); Return OK;} // call the visit () function for each element of s from the bottom of the stack to the top of the stack (), status listtraverse (sqstack S, status (* visit) (selemtype) {selemtype * P; P = S. base; For (P = S. base; P <S. top; P ++) (* visit) (* P); Return OK;} // output element estatus output (selemtype e) {printf ("% d", e ); return OK ;}
Code to evaluate an expression:
/* Calculate the value of an integer expression * The expression must end with # * The expression can contain multiple-digit characters, * the expression can contain spaces * operators include + ,-,*,/, (,) * The operation result can be a multiple-digit integer and returns */typedef int selemtype in the form of an integer;/* type of the elements placed in the stack */# include <ctype. h> # include "stack_s.c"/* determines whether the input character is an operator * C indicates the input character * op array, which stores the operators recognized by the system */status in (char C, char op []) {char * P; P = op; while (* P! = '\ 0') {If (C = * P) return true; P ++;} return false;}/* compares the priority of the two operators *, the operator * '>' in B that is to be compared indicates A> B * '0' indicates comparison that is not possible */Char precede (char a, char B) {int I, j; char pre [] [7] = {/* the priority between operators is made into a table */{'>', '>', '<', '<', '<', '>', '>'}, {'>', '>', '<', '> ', '>'}, {'>', '>', '<', '>', '>'}, {'> ', '>', '<', '>', '>'}, {'<', '<', '<', '=', '0'}, {'>', '0 ', '>', '>'}, {'<', '<', '0', '=' }; Switch (a) {Case '+': I = 0; break; Case '-': I = 1; break; Case '*': I = 2; break; Case '/': I = 3; break; Case '(': I = 4; break; Case ')': I = 5; break; Case '#': I = 6; break;} switch (B) {Case '+': J = 0; break; Case '-': j = 1; break; Case '*': j = 2; break; Case '/': J = 3; break; Case '(': J = 4; break; Case ')': J = 5; break; case '#': J = 6; break;} return pre [I] [J];}/* perform actual operations *, in B, the two operands * Theta are respectively stored as integers. Returns the */INT operate (int A, char Theta, int B) {int I, j, result; I =; j = B; Switch (theta) {Case '+': Result = I + J; break; Case '-': Result = I-j; break; Case '*': result = I * j; break; Case '/': Result = I/J; break;} return result;}/* obtain the next integer or operator from the input buffer, return to the main function through N. * If the return value is 1, the operator is obtained. * If the return value is 0, the Integer Operation is obtained. */INT getnext (int * n) {char C; * n = 0; while (C = getchar () = '');/* skip one or more spaces */if (! Isdigit (c) {/* determines through the function that if the character is not a number, it can only be the operator */* n = C; return 1 ;} do {/* can execute this statement, indicating that the character is a number, here, we use a loop to obtain consecutive numbers */* n = * n * 10 + (c-'0 '); /* convert consecutive numeric characters into corresponding integers */C = getchar ();} while (isdigit (c);/* If the next character is a number, enter the next cycle */ungetc (C, stdin);/* The new character is not a number, it may be an operator, in order not to affect the next read, put this character back in the input buffer */return 0;} int evaluateexpression () {int N; int flag; int C; char X, theta; int A, B; char op [] = "+-*/() #"; sqstack optr; sqstack opnd; initstack (& O PTR); push (& optr, '#'); initstack (& opnd); flag = getnext (& C); gettop (optr, & X); While (C! = '#' | X! = '#') {If (flag = 0) {push (& opnd, c); flag = getnext (& C) ;} else {gettop (optr, & X); Switch (precede (x, c) {Case '<': // push (& optr, c) with a low priority of the top element of the stack ); flag = getnext (& C); break; Case '=': // parentheses and accept the next character POP (& optr, & X ); flag = getnext (& C); break; Case '>': // return the operation result to the stack POP (& optr, & theta); POP (& opnd, & B); POP (& opnd, & A); push (& opnd, operate (A, Theta, B); break ;}} gettop (optr, & X) ;}gettop (opnd, & C); Return C ;}void main () {int C; printf ("Please input one expression :"); C = evaluateexpression (); printf ("result = % d \ n", c); getch ();}
Welcome to my website: http://www.zblog.us/programing/cc/expression-stack.html
| Zhao Jie's blog

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.