java中栈的应用-带括号的算术表达式

本文介绍了如何使用Java通过栈来处理带括号的算术表达式,包括将中缀表达式转换为后缀表达式以及计算后缀表达式的值。转换算法涉及运算符优先级和括号处理,计算过程利用操作数栈进行运算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题分析:

表达式有中缀表达式,后缀表达式和前缀表达式;

其中中缀表达式就是我们平常写的算术表达式,而后缀表达式就是将运算符放在两个操作数之后,前缀则放在之前;

例如:中缀表达式:A+(B-C/D)*E  对应的后缀表达式就是 ABCD/-E*+,前缀类比

由于后缀表达式中无运算优先级又无括号的约束问题,因此计算一个后缀表达式比计算一个中缀表达式咬简单



1将原算术表达式转换成后缀表达式


要使运算符出现的次序与真正的算术顺序一致,就要使优先数高的以及括号内的运算符先出现在前,所以需要一个栈来保留未被送到后缀表达式的运算符


算法思路如下:

(1)初始化一个运算符栈

(2)从算术表达式输入的字符串中从左到右读取一个字符

(3)若字符使操作数,则直接送往后缀表达式

(4)若当前字符是左括号,则压进栈内

(5)若当前字符为运算符,则进行下面操作:

      (5.1)当运算符为空时,则将其压入栈中

      (5.2)当此运算符优先级高于栈顶字符,则将其压入栈中;否则,去出栈中字符送到后缀表达式,并将当前运算符压栈

(6)若当前字符为右括号,则反复将栈顶弹出送往后缀表达式,直到栈顶为左括号为止,再将左括号丢弃

(7)若读取还未完毕,则转到步骤2

(8)若读取结束,则将栈中的运算符弹出并送往后缀表达式










2计算后缀表达式


问题分析:

要计算后缀表达式的值比较简单,只要先找到运算符,在去找之前最后两个操作数;

利用一个栈来保留后缀表达式中还未参加运算的操作数,称为操作数栈



算法分析如下:

1.初始化一个操作数栈


2从左到右依次读入后缀表达式的字符


 (1)若当前为操作数,则将操作数压入栈中


 (2)若当前为运算符,则从栈顶弹出两个操作数参与运算,并将运算结果压入操作栈中


3重复步骤2直到后缀表达式为空为止,则操作栈中的栈顶元素即为后缀表达式的计算结果

import java.util.Stack;

public class Example3_3 {
	//将算术表达式转换为后缀表达式的函数,结果一字符串的形式返回
	public String converToPostfix(String expression)throws Exception{
		Stack<Character> st=new Stack<>();   //初始化一个运算符栈
		String postfix=new String();   //用于储存后缀表达式
		for(int i=0;expression!=null&&i<expression.length();i++){
			char c=expression.charAt(i);
			if(' '!=c){
				//为左括号
				if(isOpenParent(c)){
					st.push(c);
				}//为右括号
				else if(isCloseParent(c)){
					char ac=st.pop();
					while(!isOpenParent(ac)){
						postfix=postfix.concat(String.valueOf(ac));
						ac=st.pop();
					}
				}//为运算符
				else  if(isOperator(c)){
					//运算栈非空,取出栈顶优先级高的运算符送完后缀表达式
					if(!st.empty()){
						char ac=st.pop();
						//栈取出的字符优先级比c高
						while(!st.isEmpty()&&priority(ac)>=priority(c)){
							postfix=postfix.concat(String.valueOf(ac));
							ac=st.pop();
						}//栈取出的字符优先级比c低,则将取出的字符重新入栈
						if(ac!=' '){
							st.push(ac);
						}
					}st.push(c);    //将c入栈
				}//为操作数,直接串联到postfix内
				else {
					postfix=postfix.concat(String.valueOf(c));
				}
			}
		}//当表达式读完就将算术栈pop出加入postfix
		while(!st.isEmpty()){
			postfix=postfix.concat(String.valueOf(st.pop()));
			
		}
		return postfix;
	}
	//对后缀表达式进行运算的函数
	public double numberCalculate(String postfix)throws Exception{
		Stack st=new Stack<>();//创建一个操作数栈
		for(int i=0;postfix!=null&&i<postfix.length();i++){
			char c=postfix.charAt(i);
			//如果为运算符
			if(isOperator(c)&&!st.isEmpty()){
				double d2=Double.valueOf(st.pop().toString());
				double d1=Double.valueOf(st.pop().toString());
				double d3=0;
				if('+'==c){
					d3=d1+d2;
				}
				if('-'==c){
					d3=d1-d2;
				}
				if('/'==c){
					d3=d1/d2;
				}
				if('*'==c){
					d3=d1*d2;
				}
				if('%'==c){
					d3=d1%d2;
				}
				if('^'==c){
					d3=Math.pow(d1, d2);
				}
				//将运算结果压入操作数栈中
				st.push(d3);
			}else{//为操作数时直接压入操作数栈
			st.push(c);}
		}
		return (double) st.pop();//返回运算结果
	}
	//判断字符为运算符
	public boolean isOperator(char c){
		if('+'==c||'-'==c||'/'==c||'*'==c||'%'==c||'^'==c){
			return true;
		}
		else {
			return false;
		}
	}
	//判断字符为左括号
	public boolean isOpenParent(char c){
		return c=='(';
	}
	//判断字符为右括号
	public boolean isCloseParent(char c){
		return c==')';
	}
	//判断算法的优先级
	public int priority(char c){
		if(c=='^'){
			return 3;
		}
		if(c=='/'||c=='*'||c=='%'){
			return 2;
		}
		else if(c=='-'||c=='+'){
			return 1;
		}
		else return 0;
	}
	
	

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		Example3_3 p=new Example3_3();
		String postfix =p.converToPostfix("3+2*8+(5+5)+2^2/2*5%3");
		System.out.println("表达式结果为:"+p.numberCalculate(postfix));

	}

}
运算结果
表达式结果为:30.0

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值