WUSTOJ 1208: 计算整数四则运算表达式的结果(Java)
1208: 计算整数四则运算表达式的结果
参考资料
数据结构(C语言版)严蔚敏 吴伟民 编著————表达式求值
题目
简单四则运算。更多内容点击标题。
- 保证表达式合法。
- 运算符只包含:加(+),减(-),乘(*),除(/)。
- 以等号(=)结束。
提示
- 表达式只包含:数字字符,加,减,乘,除,等号这六种符号。
- 测试数据不存在分母为0的情况,代码中不用考虑。
- 全部为int型,不存在浮点型,也就是说:3/2=1,5/2=2。
- 切记,虽然题目没说多组输入,但是测试数据有很多(我被被坑了)。
- 操作数可能不止一位,例如:10+8=。
测试数据(不像OJ的Simple Input跟没有一样QAQ)
输入
-5/2+0+1*3+14=
520=
输出
15
520
这两组数据对了,你可以直接提交了,肯定对。
分析
这道题目很明显是在考察栈的运用,不知道栈是什么的,自己参考其他资料。这里只讲题目思路。
有这本书的可以看看书(应该能看懂),没有的话,我就稍微啰嗦一下。
四则运算规则不需要我说吧。下面是这道题目的运算关系表:

这里要用到两个栈(Stack),分别是运算数栈(opnd)和运算符栈(optr)。分别保存运算符和运算数。代码声明如下:
/**
1. @Field optr 运算符栈
*/
private Stack<Character> optr;
/**
2. @Field opnd 运算数栈
*/
private Stack<Integer> opnd;
算法思想:
- 表达式最后一个字符是’=’,因此将运算符栈栈底置为’=’。
- 依次读取表达式中的每个字符,如果是数字字符,则将这个操作数进opnd栈,如果是运算符,则和optr栈顶运算符比较优先级后进行操作。
- 直到计算结束(optr栈顶和当前字符都为’='说明计算结束)。
测试数据 1 运算过程如下:
| 步骤 | optr(运算符栈) | opnd(运算数栈) | 剩余字符 | 主要操作 |
|---|---|---|---|---|
| 1 | = | -5/2+0+1*3+14= | opnd.push(0) | |
| 2 | = | 0 | -5/2+0+1*3+14= | optr.push(’-’) |
| 3 | = - | 0 | 5/2+0+1*3+14= | opnd.push(5) |
| 4 | = - | 0 5 | /2+0+1*3+14= | optr.push(’/’) |
| 5 | = - / | 0 5 | 2+0+1*3+14= | opnd.push(2) |
| 6 | = - / | 0 5 2 | +0+1*3+14= | opnd.push(calculate(5,’/’,2)) |
| 7 | = - | 0 2 | +0+1*3+14= | opnd.push(calculate(0,’-’,2)) |
| 8 | = | -2 | +0+1*3+14= | optr.push(’+’) |
| 9 | = + | -2 | 0+1*3+14= | opnd.push(0) |
| 10 | = + | -2 0 | +1*3+14= | opnd.push(calculate(-2,’+’,0)) |
| 11 | = | -2 | +1*3+14= | optr.push(’+’) |
| 12 | = + | -2 | 1*3+14= | opnd.push(1) |
| 13 | = + | -2 1 | *3+14= | optr.push(’*’) |
| 14 | = + * | -2 1 | 3+14= | opnd.push(3) |
| 15 | = + * | -2 1 3 | +14= | opnd.push(calculate(1,’*’,3)) |
| 16 | = + | -2 3 | +14= | opnd.push(calculate(-2,’+’,3)) |
| 17 | = | 1 | +14= | optr.push(’+’) |
| 18 | = + | 1 | 14= | opnd.push(14) |
| 19 | = + | 1 14 | = | opnd.push(calculate(1,’+’,14)) |
| 20 | = | 15 | = | Output(opnd.peek()) |
【备注】手打不易,且看且珍惜。
【说明】1、左边是栈底,右边是栈顶。2、剩余字符中的加粗字符(也就是最左边的字符)表示正在读取的字符。3、optr.push()表示进运算符栈;opnd.push()表示进运算数栈;calculate()表示二元运算;opnd.peek()表示获取栈顶元素(Java的Stack类自带方法);Output()表示输出。4、第18步至19步没看懂的阅读代码的getInt()方法。
下图为课本例题的过程图:

代码
/**
* time 268ms
* @author PengHao
* @version A2.0
* @date 2019-04-23 下午10:48:22
*/
import java.util.Scanner;
import java.util.Stack;
public class Main {
private Scanner sc;
/**
* @Field formal 算式
*/
private String formal;
/**
* @Field optr 运算符栈
*/
private Stack<Character> optr;
/**
* @Field opnd 运算数栈
*/
private Stack<Integer> opnd;
/**
* @Field index 正在读取的式子中的字符的下标
*/
private int index;
public Main() {
sc = new Scanner(System.in);
char temp; // 临时变量
while (sc.hasNext()) {
formal = sc.next(); // 式子
init(); // 初始化
temp = formal.charAt(index); // 获取当前字符
// 只有当前字符和运算符栈栈顶都是‘=’时,才退出循环,表示计算结束
while ('=' != temp || '=' != optr.peek()) {
if (Character.isDigit(temp)) { // 当前字符是数字
opnd.push(getInt()); // 将当前运算数入栈
} else { // 当前字符是运算符
if (0 == index) { // 这个字符是算式的第0个字符
opnd.push(0); // 将数字0入运算数栈栈顶
}
operate(); // 运算操作
}
temp = formal.charAt(index); // 获取算式的当前的字符
}
System.out.println(opnd.peek()); // 输出运算数栈栈顶(即算式结果)
}
sc.close();
}
/**
* Initializes the properties of the class
*/
private void init() {
optr = new Stack<Character>();
opnd = new Stack<Integer>();
optr.push('='); // 初始运算符栈有一个‘=’
index = 0; // 第0个字符
}
/**
* @return 式子中当前需要输入的运算数
*/
private int getInt() {
int num = 0, n;
char temp;
do {
// char型转成int型,并且下标向后移动一位
n = formal.charAt(index++) - '0';
num = num * 10 + n; // 转成运算数
temp = formal.charAt(index); // 获取当前字符
} while (Character.isDigit(temp)); // 当前字符是数字,则属于同一个运算数
return num;
}
/**
* Arithmetic operations
*/
private void operate() {
int num1, num2; // 需要计算的两个运算数
char op; // 需要计算的运算符
char a = optr.peek(); // 运算符栈的栈顶运算符
char b = formal.charAt(index); // 算式的当前的运算符
if ('>' == priority(a, b)) { // 栈里面的运算符优先级较高
num2 = opnd.pop(); // 先出栈的是第二个运算数
op = optr.pop(); // 运算符
num1 = opnd.pop(); // 后出栈的是第一运算数
opnd.push(calculate(num1, op, num2)); // 运算结果入运算数栈
} else { // 当前运算符优先级较高
optr.push(b); // 当前运算符入运算符栈
index++; // 算式下标后移一位
}
}
/**
* @param a 第一个运算符
* @param b 第二个运算符
* @return > 如果 <b>a</b> 的优先级高于 <b>b</b> 的优先级</br>
* < 如果 <b>a</b> 的优先级低于 <b>b</b> 的优先级
*/
private char priority(char a, char b) {
if ('*' == a || '/' == a) { // a运算符优先级最高
return '>';
}
if ('*' == b || '/' == b) { // b运算符优先级最高
return '<';
}
if ('=' == a) { // a是‘=’,优先级肯定是最低的
return '<';
}
return '>'; // 从左到右运算顺序,a优先级高于b(a在b左边)
}
/**
* @param num1 第一个运算数
* @param op 两个运算数之间的运算符
* @param num2 第二个运算数
* @return num1 op num2 的运算结果
*/
private int calculate(int num1, char op, int num2) {
switch (op) {
case '+':
return num1 + num2;
case '-':
return num1 - num2;
case '*':
return num1 * num2;
case '/':
return num1 / num2;
default:
return 0;
}
}
public static void main(String[] args) {
new Main();
}
}
写在最后:
- 如需转载,请于首页至少注明链接形式的wowpH的博客这几个字;
- 代码原创,如需公开引用,不能删除首行注释(作者,版本号,时间等信息)。
- 如果有疑问欢迎评论留言,尽量解答。
WUSTOJ 1208: 计算整数四则运算表达式的结果(Java)的更多相关文章
- 去空格的四则运算表达式求值-Java
笔记 package com.daidai.day4.demo1; import java.util.ArrayList; import java.util.Arrays; import java.u ...
- sql server编写简洁四则运算表达式脚本实现计算批次功能(C#等其它编程语言也能直接用此通用表达式)
问题: 在数据库编程开发中,有时会遇到数据量比较大的情况,如果直接大批量进行添加数据.修改数据.删除数据,就会是比较大的事务,事务日志也比较大,耗时久的话会对正常操作造成一定的阻塞.虽不至于达到删库跑 ...
- 数据结构课程设计四则运算表达式求值(C语言版)
本系统为四则运算表达式求值系统,用于带小括号的一定范围内正负数的四则运算标准(中缀)表达式的求值.注意事项: 1.请保证输入的四则表达式的合法性.输入的中缀表达式中只能含有英文符号"+ ...
- 大整数四则运算(vector与数组两种版本实现)
每逢大整数四则运算,都会怯懦,虽是算法竞赛必会的东西,也零散的学过,简单的总结过,但不成体系的东西心里一直没底. 所以今天消耗了大量的卡路里,啃了几套模板之后终于总结成了一套自己的模板 再也不用担心大 ...
- PAT IO-02 整数四则运算
/* *PAT IO-02 整数四则运算 *2015-07-30 *作者:flx413 */ #include<stdio.h> int main() { int a, b; scanf( ...
- JAVA计算整数的位数
/** * 计算整数的位数 * @param x * @return */ public static int countIntegerLength(int x){ final int [] size ...
- 小学生四则运算出题软件-基于java控制台的实现
.题目描述: 1. 使用 -n 参数控制生成题目的个数,例如 Myapp.exe -n 10 -o Exercise.txt 将生成10个题目. 2. 使用 -r 参数控制题目中数值(自然数.真分数和 ...
- 随机四则运算的出题程序java
一.设计思想 1.功能较多必须有菜单选择项,将一个大程序分为若干个功能模块的小程序,逐个实现2.针对题目避免重复时先将已生成的算式保存,然后将下一条生成的式子进行判断是否已生成,如果生成则返回循环语句 ...
- 结对项目:四则运算题目生成器(Java)
目录 一.需求分析 二.开发计划 三.实现方案 3.1 项目结构 3.2 代码说明 3.2.1 出题功能代码 3.2.3 批卷功能代码 3.2.3 四则运算功能代码 四.效能分析 4.1 程序效能 4 ...
随机推荐
- 20191214数组习题之三:报数(附pow函数简单用法)
- Dp优化之决策单调栈优化
证明:g(i) ≤ g(j) (i ≤ j) 令 d=g(i) , k<d , 设cut = x表示 f(i) = f(x) + w[x,i] ( x < i ) 构造一个式子: ...
- class与computed一起应用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- REST和SOAP的区别
转自:https://www.cnblogs.com/MissQing/p/7240146.html REST似乎在一夜间兴起了,这可能引起一些争议,反对者可以说REST是WEB诞生之始甚而是HTTP ...
- gis空间分析案例_坐标文件高斯投影变换地理处理工具
gis空间分析案例_坐标文件投影变换地理处理工具 商务科技合作:向日葵,135—4855__4328,xiexiaokui#qq.com 功能: 对文件进行投影变换 特点: 1. 地理处理工具,可以与 ...
- 批量转换Excel转CSV文件
本文为Excel VBA代码,可以实现将某一文件夹内的Excel文件(xls或者xlsx)另存为“逗号分隔的csv文件”. 使用条件: 1. Windows系统: 2. 已安装 MS 2007或以 ...
- “用户名不在 sudoers文件中,此事将被报告” 解决方案
第一次接触Docker是在CentOS上搭建的,没想到第一步就被弄懵了:执行sudo时提示“XXX 不在sudoers文件中,此事将被报告”. 这才刚开始就遇到个未知问题,于是上网找了下解决方法,嗨, ...
- js刷新页面location.reload()用法
转: js刷新页面location.reload()用法 2018年05月10日 10:23:28 大灰狼的小绵羊哥哥 阅读数 31359更多 分类专栏: [前端面试点滴知识 ] 本文介绍了js刷 ...
- JS 时间处理(GMT转换,超24小时加一天,时间差计算)
计算天数,加小时,加分数 Date.prototype.Format = function (fmt) { // author: meizz var o = { "M+": thi ...
- ContextCleaner ——Spark 应用程序的垃圾回收器
ContextCleaner是一个Spark服务,负责在应用程序范围内清除 shuffles, RDDs, broadcasts, accumulators和checkpointed RDDs,目的是 ...