通过栈来实现表达式的计算
主要问题在于:运算符的优先级关系处理
算法思想:
1.建立并初始化 运算符栈OPTR栈 和 数值OPND栈,将表达式起始符"#"压入OPTR栈;
2.按序获取表达式数组中每个字符串str(假定表达式是合法有效的):
->如果str表示数值:
直接压入OPND栈,进入下一次for循环;
->如果str表示运算符:
取出OPTR的栈顶运算符 top,比较str和top之间的优先级关系:
->如果优先级关系相等:
->如果top和str的均为"#":
整个表达式求值完毕 return OPND栈顶元素;
->如果栈顶元素是左括号"(",读入str为")":
那么将OPTR栈顶弹出,进入下一次for循环;
->如果top优先级大于str:
弹出OPND栈顶元素2个(b, a),弹出OPTR栈顶元素(top),然后计算:result = a top b;
将当前数组的遍历下标值减一,进入下一次for循环;
->如果top优先级小于str:
将str压入OPTR栈;
运算符之间的优先级比较:
top\str | + | - | * | / | ( | ) | # |
+ | > | > | < | < | < | > | > |
- | > | > | < | < | < | > | > |
* | > | > | > | > | < | > | > |
/ | > | > | > | > | < | > | > |
( | < | < | < | < | < | = | |
) | > | > | > | > | | > | > |
3 | < | < | < | < | < | | = |
Java代码如下:
1 package learn.normalcode;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Stack;
6
7 /**
8 * 基础表达式求值(使用2个栈完成)
9 */
10 public class BlankZ {
11
12 private static int[][] relationTable = new int[50][50];
13 static {
14 int add = '+' - '!';
15 int reduce = '-' - '!';
16 int mu = '*' - '!';
17 int div = '/' - '!';
18 int left_K = '(' - '!';
19 int right_K = ')' - '!';
20 int jin = '#' - '!';
21 int[] symbol = {add, reduce, mu, div, left_K, right_K, jin};
22 for (int i = 0; i < 7; ++i) {
23 // System.out.println(symbol[i]);
24 }
25 for (int i = 0; i < 7; ++i) {
26 relationTable[add][symbol[i]] = 1;
27 relationTable[reduce][symbol[i]] = 1;
28 relationTable[mu][symbol[i]] = 1;
29 relationTable[div][symbol[i]] = 1;
30 relationTable[left_K][symbol[i]] = -1;
31 relationTable[right_K][symbol[i]] = 1;
32 relationTable[jin][symbol[i]] = -1;
33 }
34 relationTable[add][mu] = relationTable[add][div] = relationTable[add][left_K] = -1;
35 relationTable[reduce][mu] = relationTable[reduce][div] = relationTable[reduce][left_K] = -1;
36 relationTable[mu][left_K] = -1;
37 relationTable[div][left_K] = -1;
38 relationTable[left_K][right_K] = 0;
39 relationTable[jin][jin] = 0;
40 }
41 public static boolean strIsSymbol(String str) {
42 char c = str.charAt(0);
43 return str.length() == 1 && !(c >= '0' && c <= '9');
44 }
45 public static int compare(String topSymbol, String str) {
46 return relationTable[topSymbol.charAt(0) - '!'][str.charAt(0) - '!'];
47 }
48 public static String compute(int num2, int num1, char c) {
49 int result = 0;
50 switch (c) {
51 case '+':
52 result = num1 + num2;
53 break;
54 case '-':
55 result = num1 - num2;
56 break;
57 case '*':
58 result = num1 * num2;
59 break;
60 case '/':
61 result = num1 / num2;
62 break;
63 }
64 return String.valueOf(result);
65 }
66 public static void main(String[] args) {
67 Stack<String> numbers = new Stack<>();
68 Stack<String> operators = new Stack<>();
69
70 operators.add("#");
71
72 String[] arr = {"3", "-", "2", "*", "(", "5", "+", "(", "2", "+", "0", ")", ")", "*", "3", "/", "2", "#"};
73 ArrayList<String> sentence = new ArrayList<>(11);
74 Collections.addAll(sentence, arr);
75
76 for (int i = 0; i < sentence.size(); ++i) {
77 String str = sentence.get(i);
78
79 if (strIsSymbol(str)) {
80 String topElement = operators.peek();
81 int compareResult = compare(topElement, str);
82 if (compareResult == 0) {
83 //判断是否是结束符号 #
84 if (str.equals("#")) {
85 operators.pop();
86 System.out.println(numbers.pop());
87 return;
88 } else {
89 operators.pop();
90 }
91 } else if (compareResult > 0) {
92 //取出topElement,以及numbers中的2个顶部元素,进行计算
93 operators.pop();
94 numbers.add(compute(Integer.valueOf(numbers.pop()), Integer.valueOf(numbers.pop()), topElement.charAt(0)));
95 i--;
96 } else {
97 operators.add(str);
98 }
99 } else {
100 numbers.add(str);
101 }
102 }
103 }
104 }
















