Introduction:
Here we will share an algorithm question. For example, if a mathematical expression is given, we know that the mathematical expression can use any number of matching parentheses to represent the priority. However, if the expression is long, the parentheses of this expression are often mismatched. We need to design an algorithm to check whether all the parentheses of an expression match and provide a list of matching parentheses, if not, you must also list the unmatched parentheses.
In fact, this algorithm question has some practical significance. For example, the editor in our IDE will automatically detect the method and whether the braces of the class match. The principle is the same, first, exclude all comments, and then find the matching braces in the valid content. If the braces do not match, an error is reported and the red lines are displayed in the IDE.
Analysis:
How to solve this problem:
We soon thought that we could use the stack to solve the problem. The idea was very simple. We constructed a stack. Each element in the stack contains two parts. One is whether the current parentheses are Parentheses or Closed parentheses, the position of the current bracket in the mathematical expression. Then we will scan this expression from left to right. Once we find the parentheses, We will compare it with the symbol on the top of the stack. If it is consistent with the symbol on the top of the stack, it indicates it is in the same direction as the brackets, so we press the New bracket into the top of the stack. If it is the opposite of the symbol on the top of the stack, for example, the top of the current stack is an open bracket, and you just find a closed bracket ), it indicates that a matching bracket is found, and the current bracket and the top bracket of the stack are output together with their location information. Finally, if the number of parentheses in the expression is not equal, the content in the stack is not empty after the expression is scanned, And the mismatched parentheses are output in sequence.
Considering that the expressions can be long, short, and not fixed, we use linked lists within the stack.
Code:
First, we define a POJO to express a Symbol node in the stack. It contains three pieces of information. One is that the current Symbol can only be parentheses (or Closed parentheses )), the second is the position of the current Symbol in the mathematical expression string, and the third is the reference linked to the next Symbol node.
Package com. charles. study. matchpara;/*** this class is a symbol node that can be used to verify whether the parentheses of the given expression match * @ author Administrator **/public class SymbolNode, it can be '(', it can be ')' private char symbol; // The Position of the expression indicated by the string containing this symbol is private int index; // The next node that represents the symbol private SymbolNode next; public SymbolNode (char symbol, int index, SymbolNode next) {this. symbol = symbol; this. index = index; this. next = next;} public char getSymbol () {return symbol;} public void setSymbol (char symbol) {this. symbol = symbol;} public int getIndex () {return index;} public void setIndex (int index) {this. index = index;} public SymbolNode getNext () {return next;} public void setNext (SymbolNode next) {this. next = next ;}}
Then we construct a stack data structure according to the analysis. It provides basic operations such as viewing the top elements of the stack, pushing them into the stack, and popping up the top elements of the stack.
Package com. charles. study. matchpara;/*** indicates a Stack for storing symbols, we can compare the top stack to determine whether it matches * @ author Administrator **/public class SymbolStack {// point to the top node of the stack private SymbolNode top; public SymbolStack () {top = null ;} /*** determines whether the stack is empty and determines whether the top element of the stack is null * @ return */public boolean isEmpty () {if (top = null) return true; return false;}/*** push a symbolic node to the stack * @ param symbolNode */public void push (char symbol, int index) {// if the stack is empty, use this symbolic node as the first node and assign it to top if (isEmpty () {SymbolNode symbolNode = new SymbolNode (symbol, index, null); top = symbolNode;} // If the stack is not empty, create a new symbolic node and set its next to the top node of the current stack, and itself is top else {SymbolNode symbolNode = new SymbolNode (symbol, index, null); symbolNode. setNext (top); // update the top element of the current stack to the new node top = symbolNode;}/*** get the top element of the stack */public SymbolNode getTopElement () {return top;}/*** the top element of the stack is displayed, and the next element of the top element of the stack becomes the new top element */public void pop () {// empty stack does not perform any operation if (top = null) return; // for non-empty stacks, set the next element at the top of the stack to the new top element else {top = top. getNext ();}}}
The implementation is very simple, and it is completely analyzed according to the idea we started. Finally, we write a tool class that scans the given string and analyzes the string using the stack to give the result:
Package com. charles. study. matchpara;/*** tool class for operating the symbol stack * @ author Administrator **/public class SymbolStackUtil {private SymbolStackUtil () {}/*** construct a SymbolStack * @ param expression * @ return */public static void parseExpression = \ '# \' "expression) {char symbol from a symbolic expression; symbolStack symbolStack = new SymbolStack (); SymbolNode currentTopElementInStack; // traverse this expression and find all the parentheses '(' and ')' and press them into the stack for (int I = 0; I <expression. length (); I ++) {// obtain the current character symbol = expression. charAt (I); // check whether the current character is '(' or ')' if (symbol = '(' | symbol = ')') {// compare with the current top element of the Stack to currentTopElementInStack = symbolStack. getTopElement (); // if the top element of the stack is empty, press the current symbol into the stack if (currentTopElementInStack = null) {symbolStack. push (symbol, I + 1);} // if the top element of the stack is not empty, there are two possible conditions: // If the element symbol is the same as the top element symbol of the stack, press it into the stack. Otherwise, the symbol pops up from the top of the stack, and then together with the current symbol, the output else if (currentTopElementInStack. getSymbol () = Symbol) {symbolStack. push (symbol, I + 1);} else {// print the matching brackets. out. println ("the matching brackets are:" + "" + currentTopElementInStack. getIndex () + "items" + currentTopElementInStack. getSymbol () + "match" + "" + (I + 1) + "sym" + symbol); // Delete the current symbol symbolStack from the top of the stack. pop () ;}}// when the loop is complete, if there are non-empty elements in the stack, it means these are mismatched parentheses and we print them in sequence, and remove it from the top of the stack if (! SymbolStack. isEmpty () {System. out. println ("there are still some unmatched parentheses, which are:"); while (! SymbolStack. isEmpty () {System. out. println ("Number" + symbolStack. getTopElement (). getIndex () + "sym" + symbolStack. getTopElement (). getSymbol (); // Delete the symbolStack element at the top of the stack. pop () ;}} public static void main (String [] args) {// Experiment 1 String expression1 = "(a * (B + c) + d )"; system. out. println ("Experiment 1: tested expression:" + expression1); parseExpression (expression1 ); // Experiment 2 String expression2 = "a + B * c + d * (e-g + (ax * B)-3) + 3 *) * e"; System. out. println ("Experiment 2: tested expression:" + expression2); parseExpression (expression2 );}}
Test:
Let's test it. We run the main () method of the tool class, which will check two string expressions. One is correct, and the other is not matching the opening and closing brackets. The output result is as follows:
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/140110/042H64522-0.jpg "title =" 2014-01-07_200147.jpg "alt =" wKiom1LL7NWiAsrlAACUld5Rzn4458.jpg "/>
Obviously, this is correct ..
Finally, I spoke to myself. I was ill at home today and used my top-level game desktop computer to write programs at home. It was really nice. The execution speed of the same program was more than 10 times faster than that of my company, this is a good thing. Unfortunately, you cannot stay at home every day. I will go to the company again tomorrow.
This article from "parallel line cohesion" blog, please be sure to keep this source http://supercharles888.blog.51cto.com/609344/1349561