对于一个算术表达式,我们可以用栈这种数据结构来计算它的值,也就是说可以将一个标准形式的表达式(或叫中缀表达式)转换成后缀表达式,并坚持普通的优先级法则,将一般问题浓缩成小规模问题,我们假设有运算符 + - * / ( )中缀表达式是合法的,比如 :a + b * c + ( d * e + f ) * g 转换成后缀表达式 a b c * + d e * f + g * + ,对表达式进行遍历,当读到数字字符时,把它添加到后缀表达式中,当第一次读到运算符时,将它入栈,如果栈顶元素的的优先级高于后面读到的运算符的优先级时,则该运算符入栈,否则将栈顶元素出栈。为了理解这种机制,我们把上述中缀表达式转换成后缀表达式。
首先,a被读入,把它添加到后缀表达式中,然后读到 + ,将它入栈,接着b读入并添加到后缀表达式中,然后读到 * ,此时栈顶元素是+,优先级低于*,所以将 * 入栈,接着c读入并输出到后缀表达式中。然后又读到 + , 此时我们检查一下栈,需要将 * 弹出放到后缀中,栈顶元素变成了 + ,不高于刚读到的 + ,所以将栈顶元素 + 弹出到后缀中,并将刚读到的 + 放到栈顶,此时的后缀表达式是 : a b c * + .下一个读到的的符号是 ( ,由于具有最高的优先级,所以它入栈,然后 d读入并输出到后缀中。继续进行,我们又读到 * 除非正在处理右括号 ) ,否则左括号 ( 不会从栈中弹出,所以 * 没有弹出,下一个是 e ,它被读入并输出到后缀中,。此时的后缀表达式是a b c * + d e.再往后读到 + 我们栈顶元素 * 弹出,然后将 + 入栈,然后我们读到 f 并输出到后缀中。接下来我们读到 ) 因此将栈顶元素直到 ( ,此时后缀表达式为 a b c * + d e * f + 下面又读到 * 该运算符入栈,最后g被读入并输出到后缀中。现在中缀表达式已经被遍历完了,我们将栈中所有元素弹出,直到栈变为空栈。最后后缀表达式为a b c * + d e * f + g * + 这样就得到了我们需要的结果了。下面在Java代码中实现具体的过程(myString为中缀表达式,suffixExpression为后缀表达式,集合list实现栈的结构)。
<span style="white-space:pre"> </span>for(int i =0;i<myString.length();i++){
if(myString.charAt(i) == '+'||myString.charAt(i) == '-'){ //将加减添加到后缀表达式
if(list.isEmpty()){
list.add(myString.charAt(i));
}else {
while (!list.isEmpty()) {
if(!(suffixExpression.charAt(suffixExpression.length()-1) == ' '))
suffixExpression += " ";
suffixExpression += list.get(list.size() - 1);
suffixExpression += " ";
list.remove(list.size() - 1);
}
list.add(myString.charAt(i));
}
}else if(myString.charAt(i) == '*'||myString.charAt(i) == '/'){ //将乘除添加到后缀表达式
if(list.isEmpty()){
list.add(myString.charAt(i));
}else if(list.get(list.size() - 1) == '*'
||list.get(list.size() - 1) == '/') {
do {
if(!(suffixExpression.charAt(suffixExpression.length()-1) == ' '))
suffixExpression += " ";
suffixExpression += list.get(list.size() - 1);
suffixExpression += " ";
list.remove(list.size() - 1);
if(list.isEmpty())
break;
}while (list.get(list.size() - 1) == '+'
||list.get(list.size() - 1) == '-');
list.add(myString.charAt(i));
}
else {
list.add(myString.charAt(i));
}
}else { //将数字添加到后缀表达式
suffixExpression += myString.charAt(i);
if(i+1<myString.length() && !(myString.charAt(i+1) == '.')
&& !(myString.charAt(i+1)>=48 && myString.charAt(i+1)<=57))
suffixExpression += " ";
}
}
while(!list.isEmpty()){ //所有符号出栈
if(!(suffixExpression.charAt(suffixExpression.length()-1) == ' '))
suffixExpression += " ";
suffixExpression += list.get(list.size() - 1);
list.remove(list.size() - 1);
}
System.out.println("000000");
System.out.println(suffixExpression);
for(int i = 0;i<suffixExpression.length();i++){
if(suffixExpression.charAt(i) == '+') {
int j = i-2;
while(suffixExpression.charAt(j) != ' '){ //寻找第一个空格
if(j == 0)
break;
else{
j--;
}
}
if(j == 0){
result = Double.parseDouble(suffixExpression.substring(j,i-1)); //当输入不完整时 ??? +
suffixExpression = String.valueOf(result);
break;
}else
num1 = Double.parseDouble(suffixExpression.substring(j + 1, i - 1)); //获取第一个数
System.out.println(num1);
int n = j; j--; //标记第一个空格的位置
while(suffixExpression.charAt(j) != ' '){ //寻找第二个空格
if(j == 0)
break;
else
j--;
}
if(j == 0) { //运算结束
result = Double.parseDouble(suffixExpression.substring(j,n));
System.out.println(result);
result = result + num1;
System.out.println(result);
if(i == suffixExpression.length()-1) {
suffixExpression = suffixExpression.replace(suffixExpression.substring(j), String.valueOf(result));
System.out.println(suffixExpression);
break;
}
suffixExpression = suffixExpression.replace(suffixExpression.substring(j,i+1), String.valueOf(result));
}else{
result = Double.parseDouble(suffixExpression.substring(j+1,n)); //寻找第二个数
result += num1;
System.out.println(result);
suffixExpression = suffixExpression.replace(suffixExpression.substring(j+1,i+1), String.valueOf(result));
System.out.println(suffixExpression);
}
System.out.println(suffixExpression);
i = 0;
} else if(suffixExpression.charAt(i) == '-') {
int j = i-2;
while(suffixExpression.charAt(j) != ' '){ //寻找第一个空格
if(j == 0)
break;
else{
j--;
}
}
if(j == 0){
result = Double.parseDouble(suffixExpression.substring(j,i-1)); //当输入不完整时 ??? +
suffixExpression = String.valueOf(result);
break;
}else
num1 = Double.parseDouble(suffixExpression.substring(j + 1, i - 1)); //获取第一个数
int n = j; j--; //标记第一个空格的位置
while(suffixExpression.charAt(j) != ' '){ //寻找第二个空格
if(j == 0)
break;
else
j--;
}
if(j == 0) { //运算结束
result = Double.parseDouble(suffixExpression.substring(j,n));
result -= num1;
if(i == suffixExpression.length()-1) {
suffixExpression = suffixExpression.replace(suffixExpression.substring(j), String.valueOf(result));
break;
}
suffixExpression = suffixExpression.replace(suffixExpression.substring(j,i+1), String.valueOf(result));
}else{
result = Double.parseDouble(suffixExpression.substring(j+1,n)); //寻找第二个数
result -= num1;
suffixExpression = suffixExpression.replace(suffixExpression.substring(j+1,i+1), String.valueOf(result));
}
i = 0;
} else if(suffixExpression.charAt(i) == '*') {
int j = i-2;
while(suffixExpression.charAt(j) != ' '){ //寻找第一个空格
if(j == 0)
break;
else{
j--;
}
}
if(j == 0){
result = Double.parseDouble(suffixExpression.substring(j,i-1)); //当输入不完整时 ??? +
suffixExpression = String.valueOf(result);
break;
}else
num1 = Double.parseDouble(suffixExpression.substring(j + 1, i - 1)); //获取第一个数
System.out.println(num1);
int n = j; j--; //标记第一个空格的位置
while(suffixExpression.charAt(j) != ' '){ //寻找第二个空格
if(j == 0)
break;
else
j--;
}
if(j == 0) { //运算结束
result = Double.parseDouble(suffixExpression.substring(j,n));
result *= num1;
if(i == suffixExpression.length()-1) {
suffixExpression = suffixExpression.replace(suffixExpression.substring(j), String.valueOf(result));
break;
}
suffixExpression = suffixExpression.replace(suffixExpression.substring(j,i+1), String.valueOf(result));
}else{
result = Double.parseDouble(suffixExpression.substring(j+1,n)); //寻找第二个数
result *= num1;
suffixExpression = suffixExpression.replace(suffixExpression.substring(j+1,i+1), String.valueOf(result));
}
System.out.println(result);
System.out.println(suffixExpression);
System.out.println(suffixExpression);
i = 0;
} else if(suffixExpression.charAt(i) == '/') {
int j = i - 2;
while (suffixExpression.charAt(j) != ' ') { //寻找第一个空格
if (j == 0)
break;
else {
j--;
}
}
if (j == 0) {
result = Double.parseDouble(suffixExpression.substring(j, i - 1)); //当输入不完整时 ??? +
suffixExpression = String.valueOf(result);
break;
} else {
num1 = Double.parseDouble(suffixExpression.substring(j + 1, i - 1)); //获取第一个数
if (num1 == 0) {
suffixExpression = "Error";
break;
}
}
int n = j;
j--; //标记第一个空格的位置
while (suffixExpression.charAt(j) != ' ') { //寻找第二个空格
if (j == 0)
break;
else
j--;
}
if (j == 0) { //运算结束
result = Double.parseDouble(suffixExpression.substring(j, n));
result /= num1;
if (i == suffixExpression.length() - 1) {
suffixExpression = suffixExpression.replace(suffixExpression.substring(j), String.valueOf(result));
break;
}
suffixExpression = suffixExpression.replace(suffixExpression.substring(j, i + 1), String.valueOf(result));
} else {
result = Double.parseDouble(suffixExpression.substring(j + 1, n)); //寻找第二个数
result /= num1;
suffixExpression = suffixExpression.replace(suffixExpression.substring(j + 1, i + 1), String.valueOf(result));
}
i = 0;
}
}