java 逆波兰表达式
最近想把这破机 装成WIN7 想想还是算了 ... 反正用的机会也不多。
不过 发现了一些 想念的东西
从前的作业.
从前的记忆.
package org.lmz; import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.concurrent.LinkedBlockingQueue; public class calculator_test { static String operator = "+-*/%^()"; /**
* 预处理表达式,正、负号前加0(如果一个加号(减号)出现在最前面或左括号后面,则该加号(减号)为正负号) 比如 -1-(-1+1) 这种表达式 会处理成 0-1-(0-1+1)
*/
public static String pretreatment(String str) {
StringBuffer sb = new StringBuffer(str);
for (int i = 0; i < sb.length(); i++) {
char c = sb.charAt(i);
if (operator.indexOf(c) >= 0) {
if (i == 0) {
sb.insert(0, '0');
i++;
} else if (sb.charAt(i - 1) == '(') {
sb.insert(i, '0');
i++;
}
}
}
return sb.toString();
} /***
* 0 优先级相等 ; -1 op1 优先级大于op2; 1 op2 优先级大于 op1
*/
public static int opcompare(char op1, char op2) {
if (op1 == '(') { // 遇到括号 就直接入栈 所以 op2 大
return 1;
}
if ('^' == op1) {
if (op2 == '^') {
return 0;
}
return -1;
} else if ("+-".indexOf(op1) >= 0) {
if ("+-".indexOf(op2) >= 0) {
return 0;
}
return 1;
} else // if("*/%".indexOf(op1) >=0) 没必要 再判断是否为 */% 了
{
if ("+-".indexOf(op2) >= 0) {
return -1;
} else if ('^' == op2) {
return 1;
}
return 0;
}
}
/**
* 计算传入的算术表达式
*/
public static double Calculator2(String s) throws Exception {
//预处理式子
String prestr = pretreatment(s);
//用于保存 逆波兰式 的队列
LinkedBlockingQueue<String> polish = new LinkedBlockingQueue<String>();
// 拼接 数字 char ---> numble
StringBuffer temp = new StringBuffer(); Stack<Character> stack = new Stack<Character>();
for (int i = 0; i < prestr.length(); i++) { char c = prestr.charAt(i);
//如果找到 操作符
if (operator.indexOf(c) >= 0) {
if (temp.length() > 0) {//如果 有数字 就压栈
polish.offer(temp.toString());
temp = new StringBuffer();
}
switch (c) {
case '(':
stack.push(c);
break;
case ')':
while (stack.size() > 0) {
char op = stack.pop();
if (op != '(') {
polish.offer(String.valueOf(op));
} else {
break;
}
}
break;
default:
if (stack.size() == 0) {
stack.push(c);
} else {
while (stack.size() > 0) {
char op1 = stack.lastElement();
int com = opcompare(op1, c);
if (com <= 0) {
polish.offer(String.valueOf(stack.pop()));
} else {
stack.push(c);
break;
}
}
if (stack.size() == 0) {
stack.push(c);
}
}
break;
}
} else {
temp.append(c);
}
}
if (temp.length() > 0) {
polish.offer(temp.toString());
}
while (stack.size() > 0) {
polish.offer(String.valueOf(stack.pop()));
}
System.out.println("Calcstra Queue:" + polish.toString()); return CalcstraWithQueue(polish);
}
/**
* 计算 逆波兰表达式 用队列表示
* @throws Exception 各种错误都有可能
*/
public static double CalcstraWithQueue(Queue<String> que) throws Exception {
Stack<Double> stack = new Stack<Double>();
while(true)
{
String str = que.poll();
if(str == null)
{
break;
}
if (operator.indexOf(str) >= 0) { double num2 = stack.pop();
double num1 = stack.pop();
double tempresult = 0;
switch (str.charAt(0)) {
case '+':
tempresult = num1 + num2;
break;
case '-':
tempresult = num1 - num2;
break;
case '*':
tempresult = num1 * num2;
break;
case '/':
if(num2 == 0)
{
throw new Exception("出错:除数为 0");
}
tempresult = num1 / num2;
break;
case '%':
tempresult = num1 % num2;
break;
case '^':
tempresult = Math.pow(num1, num2);
break;
default:
throw new Exception("运算符: " + str + " 未识别!");
}
stack.push(tempresult);
} else {
stack.push(Double.valueOf(str));
}
}
return stack.pop();
}
public static void main(String[] args) { Scanner reader = new Scanner(System.in);
while(true)
{
String s = reader.nextLine();
double result = 0;
try {
result = Calculator2(s);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(result);
}
}
}
java 逆波兰表达式的更多相关文章
- 逆波兰表达式 java
描述 逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系, 也不必用括号改变运算次序,例如(2 + 3) ...
- 逆波兰表达式求值 java实现代码
根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说 ...
- 蓝桥杯-逆波兰表达式-java
/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...
- Java实现 LeetCode 150 逆波兰表达式求值
150. 逆波兰表达式求值 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波 ...
- java实现第四届蓝桥杯逆波兰表达式
逆波兰表达式 正常的表达式称为中缀表达式,运算符在中间,主要是给人阅读的,机器求解并不方便. 例如:3 + 5 * (2 + 6) - 1 而且,常常需要用括号来改变运算次序. 相反,如果使用逆波兰表 ...
- lintcode 中等题:Evaluate Reverse Polish notation逆波兰表达式求值
题目 逆波兰表达式求值 在逆波兰表达法中,其有效的运算符号包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰计数表达. 样例 ["2", "1&q ...
- LeetCode:逆波兰表达式求值【150】
LeetCode:逆波兰表达式求值[150] 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除 ...
- 150 Evaluate Reverse Polish Notation 逆波兰表达式求值
求在 逆波兰表示法 中算术表达式的值.有效的运算符号包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰计数表达.例如: ["2", "1&quo ...
- leetcode算法学习----逆波兰表达式求值(后缀表达式)
下面题目是LeetCode算法:逆波兰表达式求值(java实现) 逆波兰表达式即后缀表达式. 题目: 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式.同 ...
随机推荐
- 苹果浏览器Safari对JS函数库中newDate()函数中的参数的解析中不支持形如“2020-01-01”形式
苹果浏览器safari对new Date('1937-01-01')不支持,用.replace(/-/g, "/")函数替换掉中划线即可 如果不做处理,会报错:invalid da ...
- IE中的事件对象
IE中的事件对象 1)type属性 用于获取事件类型 2)srcElement属性 用于获取事件的目标 3)cancelBubble属性 用于阻止事件冒泡 设置为true表示阻止事件冒泡 设置为fa ...
- Appium Android Bootstrap源码分析之命令解析执行
通过上一篇文章<Appium Android Bootstrap源码分析之控件AndroidElement>我们知道了Appium从pc端发送过来的命令如果是控件相关的话,最终目标控件在b ...
- 个人学习JQ插件编写成果:little酷炫的图片滑动切换效果
工作一个多月了,好久没来冒冒泡了,看了@wayong的JQ插件教程,自己编写了一个模仿拉勾网首页广告栏滑动特效的JQ插件,现在跟朋友们分享分享! 先上demo链接:http://runjs.cn/de ...
- vsphere client 虚拟机安装操系统
vSphere 是 VMware 推出的基于云计算的新一代数据中心虚拟化套件,提供了虚拟化基础架构.高可用性.集中管理.监控等一整套解决方案. VMware ESXi 是VMware vSphere ...
- .NET 开源了,Visual Studio 开始支持 Android 和 iOS 程序编写并自带 Android 模拟器
.NET 开源了,Visual Studio 开始支持 Android 和 iOS 程序编写并自带 Android 模拟器 北京时间今天凌晨的 Connect(); 大会上,多少程序员的假想成为现实. ...
- 苹果公司的新的编程语言 Swift 高级语言(十五)--协议
协议定义了适合某个特定任务或功能须要的方法.属性和其他需求的一个蓝图.协议本身不提供这些需求的实现,它仅仅是描写叙述了一个任务或功能实现的蓝图. 协议与java 语言中的接口定义类似,都是描写叙述了一 ...
- spring bean范围
总结: 实例代码具体解释: 文件夹结构 Car.java package com.coslay.beans.autowire; public class Car { private String br ...
- PBKDF2WithHmacSHA1算法
主要用于明文密码加密字符串存入数据库.由棱镜门思考.目前大部分企业中都是明文密码.一旦被攻破.危害非常大.现在主流加密技术是MD5加密.不过MD5的存在小概率碰撞(根据密码学的定义,如果内容不同的明文 ...
- W3C的CORS Specification
W3C的CORS Specification 随着Web开放的程度越来越高,通过浏览器跨域获取资源的需求已经变得非常普遍.在我看来,如果Web API不能针对浏览器提供跨域资源共享的能力,它甚至就不应 ...