在看《Algorithm》这本书时看到一个算法,可以很巧妙地实现对一个式子(字符串)实现运算,例如输入((1 + 2)* ( 1 / 2 ) ) =, 可以得到1.5.
其基本原理是:
1.构建2个栈,一个用于存储数字,一个用于存储操作符。
2.从左到右扫描字符串中的元素,直到扫描结束:
获得一个子串:
(1)若为数字,存入数字栈;
(2)若为操作符,存入操作符栈;
(3)若为左括号,不作任何操作,继续扫描;
(4)若为右括号,从数字栈连续两次弹出a1, a2;从操作符栈弹出操作符op,将结果a2 op a1结果存入数字栈
具体Java代码如下:
import java.util.Stack;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
public class DoubleStackCompute {
public static void main(String[] args) {
// TODO Auto-generated method stub
Stack<Double> numbers = new Stack<Double>();
Stack<String> op = new Stack<String>();
//判断每个字符,数字压入数字栈,操作符压入操作符栈
String str;
while (!(str = StdIn.readString()).equals("=")) {
if (str.equals("("))
continue;
else if (str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/"))
op.push(str);
else if (str.equals(")")) {
double num2 = numbers.pop();
double num1 = numbers.pop();
String c = op.pop();
double result;
if (c.equals("+")) result = num1 + num2;
else if (c.equals("-")) result = num1 - num2;
else if (c.equals("*")) result = num1 * num2;
else if (c.equals("/")) result = num1 / num2;
else continue;
numbers.push(result);
}
else {
numbers.push(Double.parseDouble(str));
}
}
StdOut.print(numbers.pop());
}
}
在编程过程中,主要遇到的问题是,两个字符串的比较直接用了“==”判断符,但是实际上应该用到String 类的equals方法,这个困扰了很长时间。
另一个问题就是,字符串的读取问题,依然不太熟练,耽误了较长时间。