逆波兰表达式(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中死锁的简单例子及其避免
死锁:当一个线程永远地持有一个锁,并且其他线程都尝试获得这个锁时,那么它们将永远被阻塞.比如,线程1已经持有了A锁并想要获得B锁的同时,线程2持有B锁并尝试获取A锁,那么这两个线程将永远地等待下去. ...
- 4th-结对编程2
0x00 Coding Coding地址/小伙伴的博客地址 合作伙伴:庞伊凡(201421123011).赵娅汀(201421123012) 0x01 题目描述 上一周大家为四则运算程序设计了2-3个 ...
- 团队作业8——第二次项目冲刺(Beta阶段)Day4--5.21
展开圆桌式会议: 会议内容:1.团队成员对昨天任务完成情况做一个简单交流,并对昨天工作中存在的问题提出集中讨论解决:2.按照昨天的昨天工作分配表做具体的任务分配:3.简单讨论明天的任务分配每个人的工作 ...
- Java-反射机制学习
反射机制是Java的一个重要性,它使得Java语言具有了动态特性.比如说,可以在代码中动态地获取某个类的信息,生成它的实例.获取其成员变量.调用它的方法.下面通过几个示例来演示反射机制的作用与用法. ...
- 201521123102 《Java程序设计》第4周学习总结
1. 本周学习总结 2. 书面作业 Q1.注释的应用 使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看.(截图) 类的注释: 方法的注释: Q2.面向对象设计(大作业1- ...
- 201521123044 《Java程序设计》第14周学习总结
1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 友情提示:导图用ctrl+鼠标滚轮放大看更清楚些 2. 书面作业 1. MySQL数据库基本操作 建立数据库, ...
- linux segmentation fault记录
文章将记录linux学习使用中出现的各种segmentation fault,持续更新,希望对看到人有所帮助 1. linux pcap segmentation fault -- 2013.11.2 ...
- python基础之socket
一.osi七层 完整的计算机系统由硬件,操作系统,软件组成. 互联网的核心就是由一堆协议组成,协议就是标准,如全世界通信的标准就是英语. 如果把计算机比作人,那么互联网协议就是计算机界的英语,所有计算 ...
- pl/sql developer 连接服务器上的数据库
1, 在本地安装的Oracle中找到目录 oracle\product\11.2.0\dbhome_1\network\admin, 它下面一般有两个文件可以进行编辑tnsnames.ora li ...
- 如何快速成长?我的java之路!
由于一些外部的原因,我不得不从自己熟悉的php领域,转战到java战场.我个人觉得还是有些心得吧,不管怎么样,或多或少可能都会有那么些经历的人,和你一起走在这世上!尽管你不知道TA是谁. 其实,转换一 ...