50字范文,内容丰富有趣,生活中的好帮手!
50字范文 > 使用栈实现中缀表达式转换成后缀表达式并计算结果(逆波兰计算器)

使用栈实现中缀表达式转换成后缀表达式并计算结果(逆波兰计算器)

时间:2023-05-06 04:38:04

相关推荐

使用栈实现中缀表达式转换成后缀表达式并计算结果(逆波兰计算器)

一、中缀表达式转换成后缀表达式

具体步骤如下:

1、初始化栈stack(暂时存放运算符)以及集合list(存放后缀表达式)

2、从左向右扫描中缀表达式

3、当前元素为数字时,直接添加到list中

4、当前元素为运算符时,需要比较当前运算符与stack中栈顶运算符的优先级

4.1、若stack为空,或者栈顶运算符为 '(' 时,当前运算符直接入栈

4.2、stack不为空,当前运算符优先级高于栈顶运算符时,则将当前运算符直接入栈;

当前运算符优先级小于等于栈顶运算符时,则将栈顶运算符出栈添加到list中,并重复4.1-4.2,将当前运算符继续与新的栈顶运算符比较。

5、当前元素为 '(' 时,直接压入stack中

6、当前元素为 ')' 时,循环stack,一次弹出stack栈顶运算符并添加到list中,直到遇到 '(' 为止,此时将栈顶运算符为 '(' 时直接出栈,继续扫描下一元素

7、重复步骤 2 至 6,直到中缀表达式被扫描完

8、将stack栈中剩余的运算符依次弹出并添加到list中,最后得到后缀表达式

例1:中缀表达式:60 + 8 / 2

例2:中缀表达式 1+((2+3)*4)-6/2

代码实现:

//1 先将表达式转换成listpublic static List<String> expressionToList(String expression){int i = 0;//下标,用于扫描表达式char ch;//用于接收扫描字符String numStr;//用于拼接多位数ArrayList<String> list = new ArrayList<String>();//存放表达式do {//需要判断ch是操作符还是数字,此处不理解的可以百度ACSII码if((ch = expression.charAt(i)) < 48 || (ch = expression.charAt(i)) > 57) {list.add(""+ch);i++;}else {//如果是数字,则需要判断是否是多位数numStr = "";while(i < expression.length() && (ch = expression.charAt(i)) >= 48 && (ch = expression.charAt(i)) <= 57) {numStr+=ch;i++;}list.add(numStr);}}while(i < expression.length());return list;}//2 将中缀表达式转为后缀表达式public static List<String> parseSuffixExpressionList(List<String> list){Stack<String> stack = new Stack<String>();ArrayList<String> resList = new ArrayList<String>();//循环中缀表达式for(String item : list) {//是多位数时直接入栈if(item.matches("\\d+")) {resList.add(item);//运算符时需要判断入栈}else if(item.equals("(")) {stack.push(item);}else if(item.equals(")")) {while(true) {if(stack.peek().equals("(")) {break;}resList.add(stack.pop());}//此时需要将)弹出stack.pop();}else {//(当前运算符优先级小于等于栈顶运算符)直接将栈顶元素出栈放入listwhile(stack.size()!=0 && priority(item) <= priority(stack.peek())) {resList.add(stack.pop());}//还需要将item压入栈中stack.push(item);}}//将栈中剩余运算符弹出放入到resListwhile(stack.size()!=0) {resList.add(stack.pop());}return resList;}//数字越大,则优先级就越高public int priority(String oper) {int result = 0;if(oper.equals("*") || oper.equals("/")) {return 2;}else if(oper.equals("+") || oper.equals("-")){return 1;}else {//System.out.println("不存在此运算符");return result;}}

二、后缀表达式计算(不包含小数情况)

具体步骤如下:

1、初始化栈stack,并将后缀表达式从左向右扫描

2、当前元素为数字时,直接入栈

3、当前元素为运算符时,依次弹出栈中两个数字,并进行运算,得到结果后入栈

4、重复1-3

直接上例子:(5+4)*3-7 对应的后缀表达式为 5 4 + 3 * 7 -

1、从左向右扫描,将 5 和 4 入栈

2、遇到运算符+,依次弹出栈中 4 和 5(4为栈顶元素,5为次顶元素),计算出 4 + 5 = 9,将 9 入栈

3、将数字 3 入栈。

4、遇到运算符 *,依次弹出栈中 3 和 7,计算出 3 * 9 = 27,将 27 入栈

5、将数字 7 入栈。

6、遇到运算符 -,依次弹出栈中 27 和 7,计算出 27 - 7 = 20,此时已扫描结束,最终结果为 20

//1 首先将表达式转换成listpublic List<String> expressionToList(String expression){int i = 0;//下标,用于扫描表达式char ch;//用于接收扫描字符String numStr;//用于拼接多位数ArrayList<String> list = new ArrayList<String>();//存放表达式do {//需要判断ch是操作符还是数字,此处不理解的可以百度ACSII码if((ch = expression.charAt(i)) < 48 || (ch = expression.charAt(i)) > 57) {list.add(""+ch);i++;}else {//如果是数字,则需要判断是否是多位数numStr = "";while(i < expression.length() && (ch = expression.charAt(i)) >= 48 && (ch = expression.charAt(i)) <= 57) {numStr+=ch;i++;}list.add(numStr);}}while(i < expression.length());//扫描结束return list;}//2 运算方法public void calculate(List<String> expressionList) {//新建一个stackStack<String> stack = new Stack<String>();int num1;//操作数int num2;int res;//运算结果//开始扫描for (String item : expressionList) {if(item.matches("\\d+")) {// \d+表示1个或多个0到9的数字,是整数部分(至少是一位整数的整数部分)//直接入栈stack.push(item);}else {//操作符,弹出两位数进行运算,运算结果重新进栈num2 = Integer.parseInt(stack.pop());num1 = Integer.parseInt(stack.pop());res = 0;//后缀表达式(逆波兰表达式)是从左向右扫描if(item.equals("+")) {res = num1 + num2;}else if(item.equals("-")) {res = num1 - num2;}else if(item.equals("*")) {res = num1 * num2;}else if(item.equals("/")) {res = num1 / num2;}else {throw new RuntimeException("运算符错误");}stack.push(res+"");}}//循环结束后只剩下运算结果System.out.println("运算结果="+stack.pop());}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。