用栈来求数值表达式。首先来分析表达式由括号、运算符合操作数组成。我们可以根据以下4种情况从左到右逐个将这些实体送入栈处理:

      1.将操作数压入操作数栈。

      2.将运算符压入运算符栈。

      3.忽略左括号

      4.在遇到右括号时,弹出一个运算符,弹出所需数量的操作数,并将运算符和操作数的运算结果压入操作数栈。

  在处理完最后一个右括号之后,操作数栈上只会有 一个值,它就是表达式的值。这种方法乍一看有些难以理解,但是要证明它能够计算得到正确的值很简单:每当算法遇到一个被括号包围并由一个运算符和两个操作数组成的子表达式时,它将都运算符合操作数的计算结果压入操作数栈。这样的结果就好像在输入中用这个值替代了该自表达式,因此用这个值替代子表达式得到的结果和原表达式相同。我们可以反复应用这个规律并得到一个最终值。

      下面是这个利用()计算算术表达式的一个列子:      

public class Evaluate {
public static void main(String[] args) throws IOException {
Stack<String> ops = new Stack<String>();
Stack<Double> vals = new Stack<Double>();
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
String str=null;
while ( (str= buf.readLine()) != null) {
if (str.equals("("))
;
else if (str.equals("+"))
ops.push(str);
else if (str.equals("-"))
ops.push(str);
else if (str.equals("*"))
ops.push(str);
else if (str.equals("/"))
ops.push(str);
else if (str.equals("sqrt"))
ops.push(str);
else if (str.equals(")")) { //当读入字符是")" ,弹出运算符和操作数,计算结果并压入栈
String op=ops.pop();
double v=vals.pop();
if (op.equals("+")) v=vals.pop()+v;
else if (op.equals("-")) v=vals.pop()-v;
else if (op.equals("*")) v=vals.pop()*v;
else if (op.equals("/")) v=vals.pop()/v;
else if (op.equals("sqrt")) v=Math.sqrt(v);
vals.push(v);
}
else if(str.equals("#"))break;
else vals.push(Double.parseDouble(str));
}
System.out.println(vals.pop());
}
}

这个栈来计算算术表达式代码写的很局限,必须有完整的()才能计算出结果,在这里我们只是介绍栈在实际中应用。

有时间我会完成这个算术表达式的完整版,用栈来实现。

 

posted on 2018-07-03 13:51  蔡苗  阅读(256)  评论(0编辑  收藏  举报