Java实现一个简单的计算器
在LeetCode上有几道题目实现简单的计算器,最近刚刚在Algorithms (4th
edition)上学习了利用栈实现简单的计算器,使用的是
E.W.Dijkstra在1960s提出的栈算法实现的。利用栈后进先出的特性,可以实现对括号以及优先级的处理。第一次尝试这种算法,写出来的代码效率也不是很高。
基本想法
首先,初始化两个栈,一个用来存储运算符(包括括号和各种运算符)。Stack<String> ops = new Stack<String>();
Stack<Integer> vals = new Stack<Integer>();
第一个程序实现的是只包括加减的,因此没有运算优先顺序,只需要考虑括号,空格等字符。基本想法是:向standard
input内输入一个字符串表达式,然后对数字和符号进行各自对应的处理。遇到一个数字,push进vals
栈,遇到一个运算符,先判断在ops
中的上一个字符是否可以进行运算(之所以这样子做是因为这样子也可以方便判断优先级),若可以进行运算,那么就将ops
中的一个符号和vals
的数pop出来进行对应的运算,然后将当前的运算符push进ops
,否则,直接将当前符号push进ops
。如果遇到右括号,直接对栈中的元素进行运算直到遇到左括号。
对于字符串转整型的处理
首先,我们可以设置一个int flag = 0
,若读取的当前字符为数字,那么就将flag
的值设为1,并且将这个数字转化为int
入栈。若当前的字符不为数字,记得一定要将flag
的值重新设为0。代码
1 2 3 4 5 6 7 8 9 10 11 int flag = 0 ;for (int i = 0 ; i < length; i++){ String currentString = s.subString(i,i+1 ); if (currentChar.charAt(0 ) >= '0' && currentChar.charAt(0 ) <= '9' ){ if (flag == 0 ) vals.push(Integer.parseInt(currentChar)); else vals.push(Integer.parseInt(Integer.toString(vals.pop())+currentChar())); flag = 1 ; } }
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 class Solution { public static int calculate (String s) { int length = s.length(); Stack<String> ops = new Stack <String>(); Stack<Integer> vals = new Stack <Integer>(); int flag = 0 ; for (int i = 0 ; i < length; i++) { String currentChar = s.substring(i, i + 1 ); if (currentChar.equals(" " )) continue ; if (currentChar.charAt(0 ) >= '0' && currentChar.charAt(0 ) <= '9' ) { if (flag == 0 ) vals.push(Integer.parseInt(currentChar)); else vals.push(Integer.parseInt(Integer.toString(vals.pop()) + currentChar)); flag = 1 ; continue ; } else if (currentChar.equals("(" ); ops.push(currentChar); else if (currentChar.equals("+" ) || currentChar.equals("-" )){ if (ops.isEmpty()); else if (ops.peek().equals("+" ) || ops.peek().equals("-" )){ int x = vals.pop(); String op = ops.pop(); if (op.equals("+" )) x = vals.pop() + x; else if (op.equals("-" )) x = vals.pop() - x; vals.push(x); } ops.push(currentChar); } else if (currentChar.equals(")" )) { String op = ops.pop(); while (!op.equals("(" )) { int x = vals.pop(); if (op.equals("+" )) x = vals.pop() + x; else if (op.equals("-" )) x = vals.pop() - x; vals.push(x); if (!ops.isEmpty()) op = ops.pop(); } } flag = 0 ; } while (!ops.isEmpty()) { String op = ops.pop(); int x = vals.pop(); if (op.equals("+" )) x = vals.pop() + x; else if (op.equals("-" )) x = vals.pop() - x; vals.push(x); } return vals.pop(); } }