标签:else 求值 运算符 理解 append 表达 计算机 abstract 构造函数
计算一个简单数学表达式(+ - * / ( ))的结果,有的这些符号的计算,常常需要看优先级来决定先算哪部分,计算机就是这个原理
两个概念:
中缀表达式(infix Expression):运算符写在两个操作数之间(运算符有一定的优先级,可以用圆括号改变运算顺序)
前/后缀表达式(prefix/postfix Expression):运算符写在两个表达式之前/之后(运算符没有优先级,没有括号,遇到运算符对它前面的两个操作数进行求值)
如中缀表达式“6*(8+7)/5”,换成后缀表达式为“6 8 7 + * 5 /”
编程思路:
函数toPostfix(),用运算符栈来存运算符,从中缀表达式第一个字符开始,如果是数字,直接加到postfix,如果是运算符号,判断和栈顶的优先级,不比栈顶的符号优先级低则入栈,(注意:栈中的“(”优先级最低,),否则,要栈顶出栈,如果是左括号,直接入栈,如果是右括号,则出栈,直到栈顶为左括号为止。
函数toValue(),用操作数栈来存数字,从后缀表达式第一个字符开始,是数字,就入栈,是运算符号就用栈顶的两个数计算结果值,结果入栈。
下面是具体代码,可以帮助理解:
元素存储,我选择用顺序表(SeqList<T>)
1 //Stack<T>接口 2 public interface Stack<T> { 3 public abstract boolean isEmpty(); 4 5 public abstract void push(T x); // 元素x入栈 6 7 public abstract T peek(); // 返回栈顶元素 8 9 public abstract T pop(); // 出栈,返回出栈元素 10 11 } 12 //顺序栈,使用顺序表存储 13 public class SeqStack<T> implements Stack<T> { 14 private SeqList<T> list; 15 16 public SeqStack(int length) { 17 this.list = new SeqList<T>(length); // 构造容量为length的空栈 18 } 19 20 public SeqStack() { 21 this(64); // 构造默认容量的空栈,调用上一个构造函数 22 } 23 24 public boolean isEmpty() { 25 return this.list.isEmpty(); 26 } 27 28 public void push(T x) { // 顺序表表尾插入元素 29 list.insert(x); 30 } 31 32 public T peek() { 33 return this.list.get(list.size() - 1); 34 } 35 36 public T pop() { 37 return list.remove(list.size() - 1); 38 } 39 } 40 //计算数学表达式 41 public class Calculate { 42 // 中缀表达式转化成后缀表达式,把运算符进入到运算符栈 43 public static StringBuffer toPostfix(String infix) { 44 Stack<String> st = new SeqStack<String>(infix.length()); 45 StringBuffer sb = new StringBuffer(2 * infix.length()); 46 int i = 0; 47 while (i < infix.length()) { 48 char ch = infix.charAt(i); 49 switch (ch) { 50 case ‘+‘: 51 case ‘-‘: 52 while (!st.isEmpty() && !st.peek().equals("(")) 53 // 栈顶不是“(”,那么都不比"+-"低,都要出栈 54 sb.append(st.pop()); 55 st.push(ch + ""); 56 i++; 57 break; 58 case ‘*‘: 59 case ‘/‘: 60 while (!st.isEmpty() 61 && (st.peek().equals("*") || st.peek().equals("/"))) 62 sb.append(st.pop()); 63 st.push(ch + ""); 64 i++; 65 break; 66 case ‘(‘: 67 st.push(ch + ""); 68 i++; 69 break; 70 case ‘)‘: 71 String out = st.pop(); // 出栈,直到为"(" 72 while (out != null && !out.equals("(")) { 73 sb.append(out); 74 out = st.pop(); 75 } 76 i++; 77 break; 78 79 default: 80 while (i < infix.length() && ch >= ‘0‘ && ch <= ‘9‘) { 81 sb.append(ch); 82 i++; 83 if (i < infix.length()) { 84 ch = infix.charAt(i); 85 } 86 } 87 sb.append(" "); 88 break; 89 } 90 91 } 92 93 while (!st.isEmpty()) 94 // 剩下的出栈 95 sb.append(st.pop()); 96 return sb; 97 } 98 99 // 后缀表达式的计算结果,运算结果入栈 100 public static int toValue(StringBuffer postfix) { 101 Stack<Integer> st = new SeqStack<Integer>(postfix.length()); 102 int value = 0; 103 for (int i = 0; i < postfix.length(); i++) { 104 char ch = postfix.charAt(i); 105 if (ch >= ‘0‘ && ch <= ‘9‘) { 106 value = 0; // 一定要先让value初始值为0 107 while (ch != ‘ ‘) { 108 value = value * 10 + ch - ‘0‘; // 字符转化为数值 109 ch = postfix.charAt(++i); // 如果这个字符为多位数 110 } 111 st.push(value); 112 } else { 113 if (ch != ‘ ‘) { 114 int y = st.pop(), x = st.pop(); // Integer自动转化为int类型 115 116 switch (ch) { 117 case ‘+‘: 118 value = x + y; 119 break; 120 case ‘-‘: 121 value = x - y; 122 break; 123 case ‘*‘: 124 value = x * y; 125 break; 126 case ‘/‘: 127 value = x / y; 128 break; 129 130 } 131 132 st.push(value); 133 } 134 } 135 136 } 137 return st.pop(); // 结果就在栈顶 138 139 } 140 141 }
标签:else 求值 运算符 理解 append 表达 计算机 abstract 构造函数
原文地址:http://www.cnblogs.com/wang118/p/7241757.html