栈的应用之中缀表达式转后缀表达式及后缀表达式的计算

问题引入:

在计算机中,后缀表达式的运行效率要高于中缀表达式,而中缀表达式转后缀表达式可以通过栈来实现,那么什么是中缀表达式和后缀表达式呢?

中缀表达式

中缀表达式其实就是我们平常使用的计算的式子,比如a+b,ab,或者再稍微复杂一点的a+bc-d/e等等

后缀表达式

后缀表达式是将操作符至于操作数之后的一种式子,运算规则是遇到操作符将前面两个操作数进行相应的运算(一般情况下操作符是二目运算符,这里的也只以二目运算符为例),比如上面的中缀表达式转换成对应的后缀表达式,分别是:ab+,ab*,abc*+de/-

算法思想:

遇到运算符将运算符入栈,后面遇到的运算符如果比栈顶运算符优先级更高或相等,则入栈,反之,栈顶的运算符出栈,直至栈顶的运算符优先级高于后面遇到的运算符为止(可以将左括号与右括号也理解为运算符,但在处理时有些特殊,左括号优先级最高,右括号优先级最低,且遇到右括号要将左括号之后的运算符全部出栈),遇到非运算符直接输出

代码实现:

这里提供的是函数,可以放到一个Demo类里用main函数去测试

	//中缀转后缀
	public String toPostfix(String str)throws Exception{
	    if(str!=null&&str!=""){
	        LinkStack lsta=new LinkStack();
	        String postfix="";
	        for(int i=0;i<str.length();i++){
	            char c=str.charAt(i);
	            if(c!=' '){
	                if(isLeftBracket(c))	lsta.push(c);
	                else if(isRightBracket(c)){
	                    while(!isLeftBracket(c)){
	                        postfix=postfix.concat(lsta.pop()+"");
                            //使用pop方法,因为要将左括号出栈
	                        c=(Character)lsta.pop();
	                    }
	                }else if(isOperator(c)){
	                    while(!lsta.isEmpty()&&prior(c)<=prior((Character)lsta.peek())){
	                        postfix=postfix.concat(lsta.pop()+"");
	                    }
	                    lsta.push(c);
	                }else postfix=postfix.concat(c+"");
	            }
	        }
	        while(!lsta.isEmpty())	postfix=postfix.concat(lsta.pop()+"");
	        return postfix;
	    }
	    throw new Exception("中缀表达式不能为空!!");
	}
	//判断是否是运算符
	public boolean isOperator(char c) {
		if(c=='+'||c=='-'||c=='*'||c=='/'||c=='%'||c=='^') return true;
		return false;
	}
	//判断左括号
	public boolean isLeftBracket(char c){
	    return c=='(';
	}
	//判断右括号
	public boolean isRightBracket(char c){
	    return c==')';
	}
	//求运算符的优先级
	public int prior(char c){
	    if(c=='+'||c=='-') return 1;
	    else if(c=='*'||c=='/'||c=='%') return 2;
	    else if(c=='^') return 3;
	    else return 0;
	}
	//计算后缀表达式
	public double runPostfix(String postfix) throws Exception{
		LinkStack lsta=new LinkStack();
		Double res=0.0;
		for(int i=0;i<postfix.length();i++) {
			char c=postfix.charAt(i);
			if(isOperator(c)) {
				try {
					Double num2=Double.parseDouble(lsta.pop()+"");
					Double num1=Double.parseDouble(lsta.pop()+"");
					if(c=='+') {
						res=num1+num2;
					}else if(c=='-') {
						res=num1-num2;
					}else if(c=='*') {
						res=num1*num2;
					}else if(c=='/') {
						res=num1/num2;
					}else if(c=='%') {
						res=num1%num2;
					}else if(c=='^') {
						res=Math.pow(num1, num2);
					}
					lsta.push(res);
				}catch(Exception ex) {
					throw new Exception("后缀表达式不合法!!");
				}	
			}
			else lsta.push(c);
		}
        res=Double.parseDouble(lsta.pop()+"");
		return res;
	}

如有任何错误的地方,望各位大佬批评指正

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值