用栈实现简单计算器
逆波兰式计算器
1) 输入一个逆波兰表达式(后缀表达式),使用栈(Stack), 计算其结果
2) 支持小括号和多位数整数,只支持对整数的计算。
思路分析:
- 从左至右扫描表达式,
- 遇到数字时,将数字压入堆栈,
- 遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 和 栈顶元素),并将结果入栈;
- 重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。
代码实现:
1. public class Polandnotation { 2. public static void main(String[] args) { 3. String suffixExpression = "30 4 + 5 * 6 -";//逆波兰表达式的字符串,每个字符用空格隔开 4. String[] s = suffixExpression.split(" "); 5. Stack<String> stack = new Stack<>(); 6. for (String s1 : s) { 7. int res = 0; 8. if (Polandnotation.isNumeric(s1)) { 9. stack.push(s1); 10. } else { 11. int num2 = Integer.parseInt(stack.pop()); 12. int num1 = Integer.parseInt(stack.pop()); 13. switch (s1) { 14. case "+": 15. res = num1 + num2; 16. break; 17. case "-": 18. res = num1 - num2; 19. break; 20. case "*": 21. res = num1 * num2; 22. break; 23. case "/": 24. res = num1 / num2; 25. break; 26. default: 27. throw new RuntimeException("ERROR!!!!"); 28. } 29. stack.push(String.valueOf(res)); 30. } 31. 32. } 33. int result = Integer.parseInt(stack.pop());//最后留在 stack 中的数据是运算结果 34. System.out.println(suffixExpression + " = " + result); 35. } 36. 37. //判断字符串是否为数字 38. public static boolean isNumeric(String str) { 39. Pattern pattern = Pattern.compile("[0-9]*"); 40. return pattern.matcher(str).matches(); 41. } 42. } 来自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php>
中缀表达式计算器
注:此计算器只能进行加减乘除,且不能使用小括号
思路分析
1、通过一个index(索引),来遍历表达式
2、如果发现是一个数字,就直接入数栈
3、如果发现扫描到的是一个符号,就分如下情况:
1、如果发现当前符号栈为空,就直接入栈
2、如果符号栈中有操作符,就进行比较:
1、如果当前的操作符的优先级小于或等于栈中的操作符,就需要从数栈中pop出两个数,从符号栈中pop出一个符号,进行运算,将得到的结果入数栈,再将当前的操作符(index所指)入符号栈。
2、如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈。
4、当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数和符号,并进行运算,将得到的结果入数栈
5、最后在数栈中的结果即为表达式的结果
代码实现:
用数组实现栈来完成,栈相关操作代码略:(arrayStack类) 1. //返回运算符的优先级,优先级是程序员来确定, 优先级使用数字表示 2. //数字越大,则优先级就越高. 3. public int priority(int oper) { 4. if (oper == '*' || oper == '/') { 5. return 1; 6. } else if (oper == '+' || oper == '-') { 7. return 0; 8. } else return -1;// 假定目前的表达式只有 +, - , * , / 9. 10. } 11. 12. //判断是不是一个运算符 13. public boolean isOper(char val) { 14. return (val == '+' || val == '-' || val == '*' || val == '/'); 15. } 16. 17. //计算方法 18. public int cal(int num1, int num2, int oper) { 19. int res = 0;//用于存放计算结果 20. switch (oper) { 21. case '+': 22. res = num1 + num2; 23. break; 24. case '-': 25. res = num2 - num1; 26. break; 27. case '*': 28. res = num1 * num2; 29. break; 30. case '/': 31. res = num2 / num1; 32. break; 33. default: 34. break; 35. } 36. return res; 37. } 来自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php> 测试类: 1. public class caculatortest { 2. public static void main(String[] args) { 3. String expression = "10 / 20 * 60"; 4. //将expression按照空格切片,获取每个操作符字符串和数字字符串,存在字符串数组s中 5. String[] s = expression.split(" "); 6. //创建两个栈:数栈和符号栈 7. arraystack numStack = new arraystack(10); 8. arraystack operStack = new arraystack(10); 9. int index = 0;//用于扫描 10. int num1, num2, res; 11. for (String s1 : s) { 12. //判断 s1 是什么,然后做相应的处理 13. if (operStack.isOper(s1.charAt(0))) {//如果是运算符 14. if (operStack.isEmpty()) { //如果发现当前符号栈为空,就直接入栈 15. operStack.push(s1.charAt(0)); 16. } else {//如果符号栈中有操作符,就进行比较 17. //如果当前的操作符的优先级小于或等于栈中的操作符 18. if (operStack.priority(s1.charAt(0)) <= operStack.priority(operStack.peek())) { 19. //需要从数栈中pop出两个数,从符号栈中pop出一个符号,进行运算, 20. // 将得到的结果入数栈, 21. // 再将当前的操作符(index所指)入符号栈。 22. num1 = numStack.pop(); 23. num2 = numStack.pop(); 24. res = numStack.cal(num1, num2, operStack.pop()); 25. numStack.push(res); 26. operStack.push(s1.charAt(0)); 27. } else {//如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈。 28. operStack.push(s1.charAt(0)); 29. } 30. } 31. } else {//如果发现是一个数字,就直接入数栈 32. int num = Integer.parseInt(s1); 33. numStack.push(num); 34. } 35. } 36. //当表达式扫描完毕,就顺序的从 数栈和符号栈中 pop 出相应的数和符号,并运行 37. while (true) { 38. //如果符号栈为空,则计算到最后的结果, 数栈中只有一个数字【结果】 39. if (operStack.isEmpty()) { 40. break; 41. } 42. num1 = numStack.pop(); 43. num2 = numStack.pop(); 44. res = numStack.cal(num1, num2, operStack.pop()); 45. numStack.push(res); 46. } 47. int result = numStack.pop();//将数栈的最后数,pop出,就是结果 48. System.out.printf("表达式 %s = %d", expression, result); 49. } 50. } 来自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php>