逆波兰表达式(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 +, -, ...
随机推荐
- STEP 7-MicroWIN SMART 西门子PLC再次安装问题
我的电脑第一次安装s7(STEP 7-MicroWIN SMART 西门子PLC)是没有问题的,有一次不小心删除,再次安装却怎么也安装不上.猫那个咪的!Why! 网上各种查资料,完全不能解决问题,有的 ...
- java伪代码《大道至简》
阅读<大道至简>第一章,深感作者对编程问题的精炼定义,通过对古老寓言故事<愚公移山>的引用,说明了编程的本质,即顺序,分支,循环.其中又将他们扮演的项目组织者,团队经理,编程人 ...
- 转:H2 入门
H2 Database做为轻量级的内嵌数据库,功能十分强大,而且运行时只需要一个jar包即可,下表是官网的描述: 更详细的对比见官网页面: http://www.h2database.com/html ...
- 团队作业1——团队展示&选题
Deadline: 2017-4-5 22:00PM,以博客发表日期为准 评分基准: 按时交 - 有分,检查的项目包括后文的四个方面 团队博客 团队选题 团队计划 团队成员贡献分分配规则 晚交 - 0 ...
- 201521123069 《Java程序设计》 第9周学习总结
1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. (1)使用try...catch语句捕获异常(try块后可跟一个或多个catch块,注意子类异常要放在父类异常前面, ...
- 控制结构(3) 状态机(state machine)
// 上一篇:卫语句(guard clause) // 下一篇:局部化(localization) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上次分析了guar ...
- Spring REST API + OAuth2 + AngularJS
http://www.baeldung.com/rest-api-spring-oauth2-angularjs 作者:Eugen Paraschiv 译者:http://oopsguy.com 1. ...
- Servlet知识点大纲
这是我整理的Servlet知识点大纲,可按照它的顺序来学习-..具体的内容在我的博客中都可以找到!
- hibernate 查询方式汇总
主要摘自 http://blog.sina.com.cn/s/blog_7ffb8dd501014a6o.html ,http://blog.csdn.net/xingtianyiyun/artic ...
- XML-为XML添加DTD-Schema方法
以后都按照如下方式为XML添加dtd或者schema 1,一般从源码jar包里找dtd文件,拷贝到自己的本地目录中: 比如mybatis在如下目录中有dtd :~/ mybatis-3.2.2-sou ...