Dijkstra双栈算术表达式求值算法
什么是stack
Stack,下压栈是基于后进先出(LIFO,Last In First Out)策略的集合类型,就像一叠邮件,每次从最顶端的邮件开始看起一样。
Dijkstra双栈算术表达式求值算法
我是用Java写的,我们先了解一下Java对于栈(Stack)这种数据类型的使用吧。
/*Item表示的是new对象时会使用的数据类型
这种特性可以用它储存任意类型的数据,称其为泛式。*/
public class Bag<Item> implements Iterable<Item>
Bag();
Item pop() //删除栈顶
void push(Item item) //在栈顶添加元素
boolean isEmpty() //判断栈是否为空
int size() //栈顶的位置
如何使用栈呢?
//创建一个整数类型的栈
public static void main(String[] args) {
Stack<Integer> stack=new Stack<Integer>(); //创建一个整数类型的栈
stack.push(12); //将12压栈
stack.push(13); //~
stack.push(14); //~
for(int c:stack)System.out.print(c+" "); //foreach,可迭代的集合类型
int x=stack.pop(); //出栈
stack.push(11);
System.out.println(stack.size()); //打印栈顶位置
System.out.println(stack.isEmpty()); //判断栈是否为空
for(int c:stack)System.out.print(c+" ");
}
/*result:
12 13 14 3
false
12 13 11
*/
进入正题
class Evalute{ //Dijkstra双栈算术表达式求值算法
private String al;
Evalute(String a){ //传入需要处理的算术式
al=a;
}
Stack<String> ops=new Stack<String>(); //操作符处理栈
Stack<Double> val=new Stack<Double>(); //数值处理栈
double cal(){
for(int i=0;i<al.length();i++){
String temp=al.charAt(i)+""; //将字符转为String
if(temp.equals("(")); //如果temp是"("的话,就跳过,处理下一个
else if(temp.equals("+")||temp.equals("-") //遇到操作符的话就需要将操作符压栈
||temp.equals("*")||temp.equals("/")) ops.push(temp);
else if(temp.equals(")")){ //这个时候要开始计算了,遇到")",开始计算,将计算结果压入数值处理栈
String op=ops.pop();
double va=val.pop();
if(op.equals("+")) va=val.pop()+va;
else if(op.equals("-")) va=val.pop()-va;
else if(op.equals("*")) va=val.pop()*va;
else if(op.equals("/")) va=val.pop()/va;
val.push(va);
}
else val.push(Double.parseDouble(temp)); //如果是数值,压栈
}
while(ops.isEmpty()==false||val.isEmpty()==false){ //还有没处理完的算术,还需要处理
String op=ops.pop();
double va=val.pop();
if(op.equals("+")) va=val.pop()+va;
else if(op.equals("-")) va=val.pop()-va;
else if(op.equals("*")) va=val.pop()*va;
else if(op.equals("/")) va=val.pop()/va;
val.push(va);
if(val.size()==1) break;
}
return val.pop();
}
}
具体实现过程
要处理的算术式为 1+(2+3)*4
-
遇到 1,为数值,将1压入数值处理栈 +(2+3)*4
-
遇到 +,为运算符,将+压入运算符处理栈 (2+3)*4
-
遇到 (,忽略
-
遇到 2,压栈 2+3)*4
-
遇到 +,压栈 +3)*4
-
遇到 3,压栈 3)*4
-
遇到 ),开始计算,运算符处理栈出栈,为 + ,将数值处理栈出栈,为 3,然后数值处理栈再出栈,为2,3+2=5,将 5 压入数值处理栈
-
遇到 *,压栈 4
-
遇到 4,压栈
-
传入的算术式已经空了,跳出for循环,进入while循环,判断条件的两个栈不能全空,我们需要继续计算
-
运算符处理栈出栈,是 * ,数值处理栈出栈,为9,再出栈,为5,将9*5=45压入数值处理栈
-
同上操作
需要注意,算完后在数值处理栈栈顶为结果,我们需要在数值处理栈栈顶位置为1时跳出循环!
完成!
总结
Dijkstra双栈算术表达式求值算法是对栈的简单运用,模拟了计算机的计算方式,需要掌握这个算法!