簡単な計算機を実現するJavaスタック



Java Stack Achieve Simple Calculator



まず、コード

コード上で直接、コード全体が2つのクラスcalc.StackCalculator.java、calc.Calculator.javaに分割されます。
1、StackCalculator.java

/** * Achieved with a stack of expression operation v1.0 * Support operations: +, -, *, /,%, ^,! , () * Enter the expression of the need to '#' End */ package calc import java.util.Stack public class StackCalculator { private Stack optr = new Stack()// operator stack private Stack opnd = new Stack()// operand stack private final Character END_Character = '#'// end character input expression public final int ADD = 0, SUB = 1, MUL = 2, DIV = 3, MOD = 4, POW = 5, FAC = 6, L_P = 7, R_P = 8, EOF = 9 public final char[][] PRI = {// operator Priority [stack] 'levle' [Current] // | ---------------- ---------------- current operator | // + -! * /% ^ () # (End character) /* + */ {'>','>','<','<','<','<','<','<','>','>'}, /* - */ {'>','>','<','<','<','<','<','<','>','>'}, / * Stack * / {'>','>','>','>','>','<','<','<','>','>'}, / * Top / * / {'>','>','>','>','>','<','<','<','>','>'}, / *% * Yun / {'>','>','>','>','>','<','<','<','>','>'}, / * Count * ^ / {'>','>','>','>','>','>','<','<','>','>'}, / * Symbol! * / {'>','>','>','>','>','>','>',' ','>','>'}, /* ( */ {'<','<','<','<','<','<','<','<','=',' '}, /* ) */ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}, /* # */ {'<','<','<','<','<','<','<','<',' ','='} } /** * Infix expression evaluation, the core of the program * @param expression * Enter a valid infix expression * @param RPN * Reverse Polish notation output (Reverse Polish Notation) * @return */ public float calcExpression(String expression, StringBuffer RPN) throws Exception { // stack operator identifier starts the initial press-fitting, corresponding end character optr.push(END_Character) // Excluding expression spaces expression = removeSpace(expression) int i = 0// read indicates the position represented by the formula while (!optr.empty()) { char currenSymbol = expression.charAt(i)// expression symbol currently scanned if (Character.isDigit(currenSymbol)) { i = readNumber(expression, i, opnd)// operand read (a number of possible) RPN.append(opnd.peek() + ' ')// included in Reverse Polish Notation } else { switch (orderBetween(optr.peek(), currenSymbol)) { case '>':// stack operator priority higher than the current operator, the operator stack 1. Remove the operator 2. Remove the data stack or a plurality of data (depending on the type of operator), 3., And operation the result onto the data stack char op = optr.pop()Remove the top of the stack // operator RPN.append(op + ' ')// When the operator can be included in the calculation process of reverse Polish notation, and the Reverse Polish expression coincides Calculator ca = new Calculator()// basic computing operation target if ('!' == op) {// Calculation of unary operators float number = opnd.pop()// remove the stack number value operation System.out.println('calculation process:' + '[' + number + ']' + '' + op + '=' + '[' +ca.calcu(number, op) +']' ) opnd.push(ca.calcu(number, op))// Calculate the results stack } else {// Calculation binary operator float number2 = opnd.pop()// remove the stack number value operation float number1 = opnd.pop()// remove the stack number value operation System.out.println('calculation process:' + '[' + number1 + ']' + '' + op + '' + '[' + number2 + ']' + '=' + '[' +ca.calcu(number1, op, number2) + ']') opnd.push(ca.calcu(number1, op, number2))// Calculate the results stack } break case '<':// stack operator priority less than the current operators, the delayed stack current operators optr.push(currenSymbol) i++ break case '=':// stack operator priority equal to the current operator, receiving the brackets and release the next character optr.pop() i++ break case ' ': throw new Exception('ERROR') } } } return opnd.pop()The results of the last element // operand stack that is needed } /** * Only focus on the interface requirements infix expression * @param expression * @return * @throws Exception */ public float calcExpression(String expression) throws Exception { return calcExpression(expression, new StringBuffer()) } /** * Reverse Polish Notation calculated on * @param rpn * @return * @throws Exception */ public float calcExpressionRpn(String rpn) throws Exception{ String[] chs = rpn.split(' ') int i = 0 int chLength = chs.length while(i new Calculator()// basic computing operation target if( convertStrToDigit(chs[i]) != null ) {// operand stack directly opnd.push(convertStrToDigit(chs[i])) } else { char op = chs[i].charAt(0) if('!'.equals( chs[i] )) { float number = opnd.pop() opnd.push(ca.calcu(number, op)) System.out.println('calculation process:' + '[' + number + ']' + '' + op + '=' + '[' +ca.calcu(number, op) +']' ) } else { float number2 = opnd.pop()// remove the stack number value operation float number1 = opnd.pop()// remove the stack number value operation System.out.println('calculation process:' + '[' + number1 + ']' + '' + op + '' + '[' + number2 + ']' + '=' + '[' +ca.calcu(number1, op, number2) + ']') opnd.push(ca.calcu(number1, op, number2))// Calculate the results stack } } i++ } return opnd.pop() } /** Converted to a floating string * * @param str * @return */ private Float convertStrToDigit(String str) { try{ float num = Float.valueOf(str) return num } catch(Exception e){ return null } } /** * The char-numeric characters into floating-point data * @param ch * @return */ private float CharToFloat(char ch) { return Float.valueOf('' + ch) } /** * The starting sub-stream analysis of the value of i, and stored in the operand stack * @param expression expression * @param parsing the start position i * @param stk resolves this value in a completed stack * @return The parsed value, return to a position next to parse expression * @throws Exception parsing error */ private int readNumber(String expression, int i, Stack stk) throws Exception { stk.push(CharToFloat(expression.charAt(i++)))// current value corresponding digit into the stack char op = expression.charAt(i) // read the next character while (Character.isDigit(op)) {// As long as there are close follow-up of digital stk.push(stk.pop() * 10 + CharToFloat(op))// pop after the original operation and the number of additional new digital, new value onto the stack again op = expression.charAt(++i)// next character } if ('.' != op) return i// If not a decimal point after the last digit, indicating completion of the analysis, the current position is returned op = expression.charAt(++i) float fraction = 1 while (Character.isDigit(op)) { stk.push(stk.pop() + CharToFloat(op) * (fraction /= 10)) op = expression.charAt(++i) } if ('.' == op) throw new Exception('ERROR')// If there is a decimal point error return i// returns the position of the current analytical character } /** * Acquiring the priority rank table (of RANK) The operator * @param op * @return * @throws Exception */ private int getOperRank(char op) throws Exception { switch (op) { case '+': return ADD case '-': return SUB case '*': return MUL case '/': return DIV case '%': return MOD case '^': return POW case '!': return FAC case '(': return L_P case ')': return R_P case '#': return EOF default: throw new Exception('ERROR') } } /** * Priority compare the stack and the current character * @param Operator stack peekOptr * @param currenOptr current scan to operator * @return Priority data item in the table * @throws Exception */ private Character orderBetween(Character peekOptr, char currenOptr) throws Exception { return PRI[getOperRank(peekOptr)][getOperRank(currenOptr)] } /** * Excluding the spaces between the strings * @param str * @return */ public String removeSpace(String str) { char[] chs = str.toCharArray() StringBuffer newStr = new StringBuffer() int i = 0 while (i if (' ' != chs[i]) { newStr.append(chs[i]) } i++ } return newStr.toString() } // test public static void main(String[] args) { StackCalculator sc = new StackCalculator() String s = '(1 + 2^3!-4)*(5!-(6-( 7-(89-0!))))#'// 2013 StringBuffer rpn = new StringBuffer() try { System.out.println('result:' + sc.calcExpression(s, rpn)) System.out.println('Reverse Polish Notation:' + rpn) System.out.println(' N calculate reverse Polish notation:') sc.calcExpressionRpn(rpn.toString()) } catch (Exception e) { e.printStackTrace() } } }

2、Calculator.java



package calc public class Calculator { /** * Unary * * @param a * Operand * @param op Operator * * @return The results Float */ public float calcu(float n, char op) throws Exception { return fact(n)// there is only a unary operator factorial } /** Binary operator * * * @param a * Operand 1 * @param op Operator * * @param b * Operand 2 * @return The results Float * @throws Exception */ public float calcu(float a, char op, float b) throws Exception { switch (op) { case '+': return a + b case '-': return a - b case '*': return a * b case '/': return div(a, b) case '%': return mod(a, b) case '^': return (float) Math.pow(a, b) default: throw new Exception('ERROR') } } private float div(float a, float b) throws Exception { if (b == 0) throw new Exception('Divisor can not be 0!') return a / b } // modulo private float mod(float a, float b) throws Exception { if (b == 0) throw new Exception('Divisor can not be 0!') return a % b } // factorial n! (N <= 20) private float fact(float n) throws Exception { if (n <0) throw new Exception('Factorial operands can not be negative!') if (n > 34) throw new Exception('Factorial can not be more than 34, otherwise out of bounds!')// may be considered to improve a larger value to cause the computing factorial if (n == 0) return 1// 0!=1 int num = (int) n if (num == n) {// n is an integer float result = 1 while (num > 0) { result *= num-- } return result } else throw new Exception('Factorial of the number of operations must be an integer!') } }

第二に、ビデオリソース

実装の詳細と論理式の評価、提案された参照Deng Junhuiデータ構造MOOCコース(ステーションbがあります)、ビデオのBaiduCloud専用式評価の下にあるリンクについて知りたい場合: https://pan.baidu.com/s/1vlkCpHTVjvzSalgrewgYoA パスワード:ixo6