逆波兰表达式(RPN)算法简单实现
一、预处理
给定任意四则运算的字符串表达式(中缀表达式),preDeal预先转化为对应的字符串数组,其目的在于将操作数和运算符分离。
例如给定四则运算内的中缀表达式:
String infix = "100+8*5-(10/2)*5+10.5";
字符串数组化后得:
{"100","+","8","*","5","-","(","10","/","2",")","+","10.5"}
二、中缀表达式转后缀表达式
规则:
遍历中缀表达式,
A、如果遇到操作数直接输出
B、如果遇到运算符,分情况:
B1:如果是*、/或者(这三个运算符,直接压栈
B2:如果是),则出栈直到遇到(位置。(左括号和有括号并不参与拼接后缀表达式)。
B3:如果是+或者-,先弹栈直到栈空,再讲当前的+或者-压栈。
其中情况B可以总结:
遇到右括号出栈直到匹配左括号,遇到操作符,如果其优先级高于栈顶元素,则继续压栈,否则出栈。
三、计算后缀表达式
规则:
遍历后缀表达式:
A、遇到操作数压栈
B、遇到运算符则将栈顶和次栈顶两个元素取出参与对应的运算,再将运算结结果压栈。
四、Java算法实现
package agstring;
import java.util.*; public class RPN {
public static String[] preDeal(String infix){
infix = infix.trim();
int length = infix.length();
ArrayList<String> infixOfArrayList = new ArrayList<String>();
char currChar;
int index = 0;
final String regex = "\\+|-|\\*|\\/|\\(|\\)";
for (int i = 0; i < length; i++) {
currChar = infix.charAt(i);
if(String.valueOf(currChar).matches(regex)){//运算符
if (index < i) {
infixOfArrayList.add(infix.substring(index,i));//add数字
}
infixOfArrayList.add(String.valueOf(currChar));
index = i+1;
}
}
infixOfArrayList.add(infix.substring(index,length));
return infixOfArrayList.toArray(new String[infixOfArrayList.size()]);
}
public static String[] getPostfix(String infix) {
String[] infixOfAry = preDeal(infix);
int length = infixOfAry.length;
ArrayDeque<String> stack = new ArrayDeque<String>();
String currString = "";
final String regex = "\\+|-|\\*|\\/|\\(|\\)";
ArrayList<String> postfixOfArrayList = new ArrayList<String>();
for (int i = 0; i < length; i++) {
currString = infixOfAry[i];
if (currString.matches(regex)) {//symbol
if (currString.matches("\\*|\\/|\\(")) {
stack.offerFirst(currString);
}else {//),+,-
String top = "";
if(currString.equals(")")){
while(!stack.isEmpty()){
top = stack.removeFirst();
if (top.equals("(")) {
break;
}
postfixOfArrayList.add(top);
}
}else {//+ ,-
if (!stack.isEmpty()) {
top = stack.peekFirst();
if (top.equals("*") || top.equals("/")) {
while(!stack.isEmpty()){
postfixOfArrayList.add(stack.removeFirst());
}
}
}
stack.offerFirst(currString);
}
}
}else {//number
postfixOfArrayList.add(currString);
}
}
while(!stack.isEmpty()){
postfixOfArrayList.add(stack.removeFirst());
}
return postfixOfArrayList.toArray(new String[postfixOfArrayList.size()]);
}
public static double computePostfix(String infix){
String[] postfixAry = getPostfix(infix);
ArrayDeque<Double> stack = new ArrayDeque<Double>();
int length = postfixAry.length;
String currString = "";
final String regex = "\\+|-|\\*|\\/|\\(|\\)";
double operandOne,operandTwo;
for (int i = 0; i < length; i++) {
currString = postfixAry[i];
if (currString.matches(regex)) {
operandOne = stack.removeFirst();
operandTwo = stack.removeFirst();
switch (currString.charAt(0)) {
case '+':
stack.addFirst(operandTwo + operandOne);
break;
case '-':
stack.addFirst(operandTwo - operandOne);
break;
case '*':
stack.addFirst(operandTwo * operandOne);
break;
case '/':
stack.addFirst(operandTwo / operandOne);
break;
} }else {
stack.addFirst(Double.parseDouble(currString));
}
}
return stack.removeFirst();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
String infix = "100+8*5-(10/2)*5+10.5";
double result = computePostfix(infix);
System.out.println(result);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
} }
(完)
转载请注明原文出处:http://www.cnblogs.com/qcblog/p/7502666.html
逆波兰表达式(RPN)算法简单实现的更多相关文章
- nyoj35——逆波兰表达式
逆波兰表达式又称作后缀表达式,在四则混合运算的程序设计中用到. 例如: 1+2写成后缀表达式就是12+ 4+5*(3-2)的后缀表达式就是4532-*+ 后缀表达式在四则运算中带来了意想不到的方便,在 ...
- shunting-yard 调度场算法、中缀表达式转逆波兰表达式
中缀表达式 1*(2+3) 这就是一个中缀表达式,运算符在数字之间,计算机处理前缀表达式和后缀表达式比较容易,但处理中缀表达式却不太容易,因此,我们需要使用shunting-yard Algorith ...
- 面试题42:计算逆波兰表达式(RPN)
这是一个比较简单的题目,借助栈可以轻松实现逆波兰表达式. 题目描述: Evaluate the value of an arithmetic expression in Reverse Polish ...
- leetcode算法学习----逆波兰表达式求值(后缀表达式)
下面题目是LeetCode算法:逆波兰表达式求值(java实现) 逆波兰表达式即后缀表达式. 题目: 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式.同 ...
- C++基础算法学习——逆波兰表达式问题
例题:逆波兰表达式逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 ...
- ACM -- 算法小结(六)逆波兰表达式
逆波兰表达式 //问题描述:逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2+3的 //逆波兰表达式法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必 //用括号改 ...
- C#数据结构与算法系列(十):逆波兰计算器——逆波兰表达式(后缀表达式)
1.介绍 后缀表达式又称逆波兰表达式,与前缀表达式相似,只是运算符位于操作数之后 2.举例说明 (3+4)*5-6对应的后缀表达式就是3 4 +5 * 6 - 3.示例 输入一个逆波兰表达式(后缀表达 ...
- 逆波兰表达式的C实现
复习下数据结构,用栈简单实现逆波兰表达式,参考文档: http://www.nowamagic.net/librarys/veda/detail/2307 http://www.nowamagic.n ...
- 150. Evaluate Reverse Polish Notation逆波兰表达式
[抄题]: Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are ...
- [LeetCode] 150. Evaluate Reverse Polish Notation 计算逆波兰表达式
Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...
随机推荐
- 聊一聊我们都熟知的 “ Java分层 ”
一.为什么要分层. 以前的我们,写代码的时候,都在main()方法中,出现了错误,就慢慢调试,这样浪费了我们很长的时间,而我们程序员的时间是非常宝贵的 但是当我们使用分层架构的时候,就可以清晰明确的知 ...
- 团队作业8——Beta 阶段冲刺1st day
一.今日站立式会议照片 二.每个人的工作 (1) 昨天已完成的工作: 今天是冲刺的第一天,昨天完成的是团队成员任务的分配 (2) 今天计划完成的工作: 界面的完善 (3) 工作中遇到的困难: 对于界面 ...
- 团队作业10--Beta阶段项目复审
小组的名字和链接 优点 缺点 最终排名 油炸咸鱼 http://www.cnblogs.com/24app/ 基本功能实现,能够完成预期达到的大部分功能,并能够修复所有自己提出的bug,界面也还行,博 ...
- 201521123069 《Java程序设计》 第8周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 1.2 选做:收集你认为有用的代码片段 (1)泛型允许指定集合中元素的类型,在编译时就可以进行类型检查,避免运 ...
- 201521044091《Java程序设计》第7周学习总结
1. 本周学习总结 ArrayList代码分析 1.1 解释ArrayList的contains源代码 用于判断Collection中是否包含某个元素.List<T>的contains方法 ...
- 201521123114《Java程序设计》第1周学习总结
1. 本周学习总结 java语言具有:简约且简单,平台无关性,面向对象,多线程.分布性.高性能.健壮性等特点. 2. 书面作业 1.为什么java程序可以跨平台运行?执行java程序的步骤是什么? J ...
- 201521123033《Java程序设计》第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...
- 聊聊React高阶组件(Higher-Order Components)
使用 react已经有不短的时间了,最近看到关于 react高阶组件的一篇文章,看了之后顿时眼前一亮,对于我这种还在新手村晃荡.一切朝着打怪升级看齐的小喽啰来说,像这种难度不是太高同时门槛也不是那么低 ...
- Eclipse dynamic web project 插件
下载了Eclipse Oxygen 发现没有Dynamic web Project 首先我们先了解下Dynamic Web Project If you want to create a c ...
- (转)添加PROPAGATION_REQUIRES_NEW 事务没有产生作用
最近在做事务添加时 发现自己的事务没有新建,上网查到 仅用作收藏. 其二 注意 事务的注解 应该在 内层的事务上面 一.描述 Spring遇到嵌套事务时,当被嵌套的事务被定义为" ...