In computer science, stack is a linear table that is only inserted or deleted at the end of a table.
Stack is a data structure. It stores data based on the principle of "first-in-first-out". The first data is pushed to the bottom of the stack, and the last data is placed at the top of the stack, data is popped up from the top of the stack when data needs to be read.
In various language environments, such as C ++, Java, or C #, two basic functions (push and pop) are provided for the stack, these are used to load objects into the stack and pop-up objects from the stack respectively.
Stack implementation can be implemented in two ways:
(1) linked list implementation. This method uses a linked list to store data. The stack pressure operation is equivalent to inserting a new node at the beginning of the linked list, and the stack output operation is equivalent to deleting the starting node at the beginning of the linked list.
(2) array implementation. Another method of stack implementation is to use arrays, which is also the most common implementation method. We use an array object to store data and define a variable to indicate the position at the top of the stack.
We know that in Java, the size of an array object cannot be changed after initialization, but the size of the stack should be changed according to the actual situation, this requires us to determine the implementation of the stack.
Whether the array is full and the size of the stack is expanded. In JDK, we can see that stack implementation is implemented through arrays. In the stack. Java file, we can see that
Class Stack <E> extends vector <E>
In the above, we can see that the stack inherits vector, and the implementation of data in the vector is stored through arrays.
There are many stack applications. The following describes two classic stack applications.
(1) symbol matching
As we all know, the compiler will check for syntax errors when compiling a program. One of the main contents is to check whether the symbol appears. For example, [{}] is a compliant syntax, and {[}] does not.
Stack-based algorithm for file symbol matching can be described as follows:
First, create an empty stack and read characters from the file. If the symbol is an open symbol, such as "{", "[" and "(", press the symbol into the stack. If it is a closed symbol, if the stack is empty, an error is reported,
If it is not empty, an open character will pop up from the stack. If the pop-up open character corresponds to the original closed character, it will continue to read the character from the file. If not, an error is reported. When reading the end of a file, check the stack
Is it empty? If it is empty, there is no syntax error. If it is not empty, a syntax error is reported.
(2) Suffix expression
When we calculate a mathematical expression that contains +,-, *,/, (,), and 0-9 digits, we first use the stack to convert the mathematical expression to a suffix expression, then use the stack to calculate the suffix expression.
First, let's talk about how to convert a calculated expression to a suffix expression. The priority of operators must be considered in the conversion process. The following lists the priorities:
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 steps for parsing arithmetic expressions using stacks are as follows:
(1) obtain a letter ch from left to right
(2) If ch is a character, it is output directly.
(3) If ch is an operator, then:
A. If CH = '(', put it into the stack;
B. If CH = ')', output the operators in the stack in sequence until ')' is encountered ')';
C. if ch is not '(' or ')', you need to compare the top of the CH and the top of the stack. If CH has a higher priority than top, press ch into the stack. If the priority of CH is lower than or equal to the top
Priority, output top, and press ch into the stack.
(4) If the expression has been read, and there are operators in the stack, the operators are output from the stack in sequence.
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 /-
After using the above algorithm, we can get a suffix expression corresponding to the operation expression. Next, we will parse the suffix expression to calculate the calculated value.
The parsing process is as follows:
(1) scan the expression from left to right to retrieve a data Ch at a time;
(2) If ch is the operand, It is pushed into the stack;
(3) If ch is an operator, the number of operations required by the operator is displayed in the stack, and the calculation result is pushed to the stack;
(4) If the data processing is complete, the final data left in the stack is the result of the final calculation.
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) Obtain '-', which is an operator. The data 15, 1.2 is displayed, and the data 13.8 is obtained. This is the final calculation result.
Instance code:
Public class posfixparser
{
Private Static string expression = "1 + 4/(1 + 1) + 2*(3 + 4)-6/3 + 5/(1/2 + 2/1 )";
Private Static stack mystack = new stack ();
Private Static stringbuilder posfixexpression = new stringbuilder ();
Public static void main ()
{
Console. writeline ("This midfix expression is: {0}", expression );
Console. writeline ("The posfix expression is: {0}", parse ());
Console. writeline ("the result is {0}", calculate ());
Console. Read ();
}
// Resolve the infix expression to a suffix expression
Public static string parse ()
{
Int I, j = 0;
Char CH, substring;
Char [] A = expression. tochararray (); // convert a string to a character array. Note that there cannot be a number greater than 10.
Char [] B = new char [A. Length]; // The Last generated suffix expression is smaller than this length because of parentheses.
Int length = A. length;
For (I = 0; I <length; I ++)
{
Ch = A [I];
If (isoperand (CH) // if it is an operand, directly put it in B
{
B [J ++] = CH;
}
Else
{
If (CH = '(') // if it is '(', put it in the stack
Mystack. Push (CH );
Else if (CH = ') // if it is ')'
{
While (! Isempty (mystack) // the content in the stack is continuously popped up '('
{
Ch = (char) mystack. Pop ();
If (CH = '(')