后缀表达式 (又称 逆波兰表达式) Java代码的简单实现
表达式求值问题
好久没有发随笔了,最近学习复习数据结构的时候看到了后缀表达式(逆波兰表达式)
发现了栈的精巧,自己想实现一下,本来想用C写的,但是实在太困难了,所有写了个简单的Java版本,还可以的
输入中缀表达式 可以得到计算结果
- 中缀表达式
- 后缀表达式 (又称 逆波兰表达式)
- 前缀表达式(又称 波兰表达式)
中缀表达式 | 后缀表达式 | 前缀表达式 |
---|---|---|
a+b | ab+ | +ab |
a+b-c | ab+c- | -+abc |
a+b-c*d | ab+cd*- | -+ab*cd |
利用栈实现输入中缀字符串完成后缀计算
Java代码
由于c代码不好字符串转小数,也不好记录连续的数字,所有采用java实现;这里只涉及+ - * /(加减乘除)
package com.mhy.calculate; import java.util.ArrayDeque; import java.util.Deque; public class Calculate { public static void main(String[] args) { Calculate calculate = new Calculate(); String str = "11.2*88.9-(5*8+83.5-99)+55-88/44-(8+2-3+(55*8))-11.18-46+1"; System.out.println(calculate.calculate(str)); //521 } public double calculate(String str){ int nums = 0;//记录数字个数 int length = str.length();//字符串的长度 Deque<Double> numQ = new ArrayDeque<>();//数字栈 Deque<Character> charQ = new ArrayDeque<>();//符号栈 for (int i = 0; i < length; i++) { char x = str.charAt(i); if(isNum(x)){//如果x是数或者小数点 nums++; }else { if(nums != 0){//数字入栈 double v = Double.parseDouble(str.substring(i - nums, i));//截取小数 numQ.offerFirst(v);//数字入栈 } nums = 0;//重置记录个数 if(x == '('){//判断是否为'(', charQ.offerFirst(x); continue; }else if(charQ.isEmpty()){//判断是否为空 charQ.offerLast(x); continue; } while(true){//符号栈的弹出操作 if(charQ.isEmpty()) {//如果为空了 if(x != ')'){//并且这个字符不是')'就入栈 charQ.offerFirst(x); } break;//结束循环 } char y = charQ.peekFirst();//获取符号的栈顶元素 if(y == '(' && x == ')') {//如果栈顶为'(' 且 需要入栈的是')' charQ.pollFirst();//就直接'('弹出栈,')'不入栈 break;//结束循环 } if(y == '(' && x != ')'){//如果栈顶为'(' 且 需要入栈的不是')' charQ.offerFirst(x);//直接入栈 break;//结束循环 } if(x == ')'){//如何入栈的是')' 开始弹栈进行运算 char p = charQ.pollFirst();//栈顶符号 double b = numQ.pollFirst();//后操作数 double a = numQ.pollFirst();//前操作数 numQ.offerFirst(cal(a,b,p));//结果入栈 continue; } if(operatorsRules(x,y)){//如果不是')',就符号比较,大于等于就运算 charQ.pollFirst(); double b = numQ.pollFirst(); double a = numQ.pollFirst(); numQ.offerFirst(cal(a,b,y)); }else {//否则符号入栈 charQ.offerFirst(x); break; } } } } if(nums != 0){//数字入栈 由于中缀输入都是以数字结尾,所以最后还需要进行运算 double v = Double.parseDouble(str.substring(length - nums, length)); numQ.offerFirst(v); } while(!charQ.isEmpty()){//把符号栈谈完 char p = charQ.pollFirst(); double b = numQ.pollFirst(); double a = numQ.pollFirst(); numQ.offerFirst(cal(a,b,p)); } return numQ.pollFirst();//最好数字栈的栈顶就是结果 } //是否为数 public boolean isNum(char x){ if(x == '.') return true; return x >= 48 && x <= 57; } //计算 public Double cal(double a,double b,char x){ if(x == '*') return a*b; if(x == '/') return a/b; if(x == '-') return a-b; if(x == '+') return a+b; return null; } //符号优先级判断 public boolean operatorsRules(char x,char y){ if(x == '*' || x== '/'){ if(y == '*') return true; else if(y == '/') return true; else if(y == '+') return false; else if(y == '-') return false; } if(x == '+' || x == '-'){ if(y == '-') return true; else if(y == '+') return true; else if(y == '*') return true; else if(y == '/') return true; } System.out.println("符号输入错误"); return false; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)