题目:

问题描述
  输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
  输入一行,包含一个表达式。
输出格式
  输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
  表达式长度不超过100,表达式运算合法且运算过程都在int内进行。
 
 

初看此题,从人的直观角度来说很简单,先遍历括号内的运算完再重新遍历,但是很麻烦。

回忆起了后缀表达式的知识

中缀表达式转后缀表达式的方法:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。

后缀表达式的计算机求值:
与前缀表达式类似,只是顺序是从左至右:
从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。
例如后缀表达式“3 4 + 5 × 6 -”:
(1) 从左至右扫描,将3和4压入堆栈;
(2) 遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素,注意与前缀表达式做比较),计算出3+4的值,得7,再将7入栈;
(3) 将5入栈;
(4) 接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈;
(5) 将6入栈;
(6) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。

一开始,我先把中缀表达式转换为后缀表达式,再对后缀表达式求值。

有一个很大的问题,数字的保存,转化为后缀表达式时保存为char字符,对于大于9的数字保存很麻烦。

后来想了想,可以直接借用后缀表达式的计算方法。

代码如下

 public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
Stack<Integer> nums = new Stack<Integer>(); // 保存数字
Stack<Character> opes = new Stack<Character>(); // 保存操作符
String string = scanner.nextLine();
int n = 0; // 保存每一个数字
char[] cs = string.toCharArray();
for (int i = 0; i < cs.length; i++) {
char temp = cs[i];
if (Character.isDigit(cs[i])) {
n = 10 * n + Integer.parseInt(String.valueOf(cs[i])); // 大于10的数字保存
} else {
if (n != 0) {
nums.push(n);
n = 0;
}
if (temp == '(') {
opes.push(temp);
} else if (temp == ')') {
while (opes.peek() != '(') { // 括号里面运算完
int t = cal(nums.pop(), nums.pop(), opes.pop());
nums.push(t);
}
opes.pop();
} else if (isType(temp) > 0) {
if (opes.isEmpty()) { // 栈为空直接入栈
opes.push(temp);
} else {
// 若栈顶元素优先级大于或等于要入栈的元素,将栈顶元素弹出并计算,然后入栈
if (isType(opes.peek()) >= isType(temp)) {
int t = cal(nums.pop(), nums.pop(), opes.pop());
nums.push(t);
}
opes.push(temp);
}
}
}
}
// 最后一个字符若是数字,未入栈
if (n != 0) {
nums.push(n);
}
while (!opes.isEmpty()) {
int t = cal(nums.pop(), nums.pop(), opes.pop());
nums.push(t);
}
System.out.println(nums.pop());
} // 返回的是运算符的优先级,数字和()不需要考虑
public static int isType(char c) {
if (c == '+' || c == '-') {
return 1;
} else if (c == '*' || c == '/') {
return 2;
} else {
return 0;
}
} // 运算次序是反的,跟入栈出栈次序有关
public static int cal(int m, int n, char c) {
int sum = -987654321;
if (c == '+') {
sum = n + m;
} else if (c == '-') {
sum = n - m;
} else if (c == '*') {
sum = n * m;
} else if (c == '/') {
sum = n / m;
}
return sum;
}
}

表达式计算 java 后缀表达式的更多相关文章

  1. [Swust OJ 322]--东6宿舍灵异事件(中缀表达式转化为后缀表达式的简单运用)

    题目链接:http://acm.swust.edu.cn/problem/322/ Time limit(ms): 1000 Memory limit(kb): 65535     Descripti ...

  2. 蓝桥杯 ALGO-156 表达式计算 JAVA代码 栈的应用

     算法训练 表达式计算   时间限制:1.0s   内存限制:256.0MB      问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个 ...

  3. Java堆栈的应用2----------中缀表达式转为后缀表达式的计算Java实现

    1.堆栈-Stack 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...

  4. 《java数据结构与算法》笔记-CH4-8栈结构实现后缀表达式计算结果

    /** * 中缀表达式转换成后缀表达式: 从输入(中缀表达式)中读取的字符,规则: 操作数: 写至输出 左括号: 推其入栈 右括号: 栈非空时重复以下步骤--> * 若项不为(,则写至输出: 若 ...

  5. 数据结构Java实现06----中缀表达式转换为后缀表达式

    本文主要内容: 表达式的三种形式 中缀表达式与后缀表达式转换算法 一.表达式的三种形式: 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3.我们从小做数学题时,一直使用的就是中缀表达式. 后 ...

  6. Java数据结构和算法(六)——前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  7. java四则运算----前缀、中缀、后缀表达式

    接到一个新需求,需要实现可配置公式,然后按公式实现四则运算. 刚拿到需求,第一反应就是用正则匹配‘(’,‘)’,‘+’,‘-’,‘*’,‘/’,来实现四则运算,感觉不复杂. 然后开始coding.发现 ...

  8. 实现Linux下dc的功能,计算后缀表达式的值

    提交测试截图和码云练习项目链接,实现Linux下dc的功能,计算后缀表达式的值 -将运算符写在两个操作数之后的表达式称为"后缀表达式",如上面的中缀表达式可转换为后缀表达式1 2 ...

  9. 【java】中缀表达式转后缀表达式 java实现

    算法: 中缀表达式转后缀表达式的方法:1.遇到操作数:直接输出(添加到后缀表达式中)2.栈为空时,遇到运算符,直接入栈3.遇到左括号:将其入栈4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出 ...

随机推荐

  1. Java泛型中的通配符的使用

    package com.srie.testjava; import java.util.ArrayList; import java.util.List; public class TestClass ...

  2. 利用apache的mod_rewrite做URL规则重写

    使用mod_rewrite做url重写,伪静态,做过很多次,这次用几个例子记下来,便于后面查用. 使用方法: 1.在conf目录的httpd.conf文件中找到: LoadModule rewrite ...

  3. 用Mockito测试SpringMVC+Hibernate

    用Mockito测试SpringMVC+Hibernate 译自:Spring 4 MVC+Hibernate 4+MySQL+Maven integration + Testing example ...

  4. Socket层上的协议

    Socket层上的协议指的数据传输的格式 HTTP协议 传输格式:假设:这是假设,实际http的格式不是这样的. http1.1,content-type:multipart/form-data,co ...

  5. 雷锋推到雷峰塔,Java implements Javascript。

    最近遇到这么一个问题,如何让用户在软件中自定义函数. 举个例子,使用Java做一个小的监控系统,用户A希望CPU超过90%的时候报警,B用户希望内存超过90%的时候报警,C用户希望CPU超过90%或者 ...

  6. cmake的两个命令: option 和 configure_file

    本节要讨论的是cmake的两个命令: option 和 configure_file option 选项,让你可以根据选项值进行条件编译. configure_file 配置文件,让你可以在代码文件中 ...

  7. redisson实现分布式锁原理

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  8. JS闭包深入理解(理解篇)

    看书的时候很是不明白为啥变量老是五,经过认真思考的出一下理解: function box() {   var arr = [];   for (var i = 0; i < 5; i++) {  ...

  9. 融云发送手机短信验证短信(.net版本)

    首先本次需求是在MVC5中进行的,通过收费的融云服务来验证手机号码,而且本次的项目也是前后台分离,所以添加了WEBAPI2,那么先添加WEBAPI的接口 using System; using Sys ...

  10. Ffmpeg 视频教程

    最近一段时间找时间录制了一些Ffmpeg视频教程,还有录制完毕,会持续更新,内容会包含Ffmeg保存文件,网络流转发, 编码,解码,播放器制作,以及服务端搭建等等,适合初学者,有需要的朋友的可以关注: ...