用栈实现简单计算器

逆波兰式计算器

1) 输入一个逆波兰表达式(后缀表达式),使用栈(Stack), 计算其结果
2) 支持小括号和多位数整数,只支持对整数的计算。

思路分析:

  1. 从左至右扫描表达式,
  2. 遇到数字时,将数字压入堆栈,
  3. 遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 和 栈顶元素),并将结果入栈;
  4. 重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。

代码实现:

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> 

 

posted @ 2020-10-16 14:55  白刃天使  阅读(779)  评论(0编辑  收藏  举报