双栈算术表达式求值算法

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,为数值,将1压入数值处理栈 +(2+3)*4
    在这里插入图片描述

  2. 遇到 +,为运算符,将+压入运算符处理栈 (2+3)*4
    在这里插入图片描述

  3. 遇到 (,忽略

  4. 遇到 2,压栈 2+3)*4
    在这里插入图片描述

  5. 遇到 +,压栈 +3)*4
    在这里插入图片描述

  6. 遇到 3,压栈 3)*4
    在这里插入图片描述

  7. 遇到 ),开始计算,运算符处理栈出栈,为 + ,将数值处理栈出栈,为 3,然后数值处理栈再出栈,为2,3+2=5,将 5 压入数值处理栈
    在这里插入图片描述

  8. 遇到 *,压栈 4
    在这里插入图片描述

  9. 遇到 4,压栈
    在这里插入图片描述

  10. 传入的算术式已经空了,跳出for循环,进入while循环,判断条件的两个栈不能全空,我们需要继续计算

  11. 运算符处理栈出栈,是 * ,数值处理栈出栈,为9,再出栈,为5,将9*5=45压入数值处理栈
    在这里插入图片描述

  12. 同上操作
    在这里插入图片描述
    需要注意,算完后在数值处理栈栈顶为结果,我们需要在数值处理栈栈顶位置为1时跳出循环!
    完成!

总结

Dijkstra双栈算术表达式求值算法是对栈的简单运用,模拟了计算机的计算方式,需要掌握这个算法!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值