基于Java语言的表达式计算

一个表达式包含+、—、*、/、()运算符,要计算表达式的值。此处运用栈,分别存储操作数和操作符,大体思路是利用双栈把中缀表达式转换成后缀表达式进行计算。

1.拆分数字与运算符
遇到运算符截断、存储、清空。
2.转后缀表达式
栈A存放后缀表达式,栈B存放运算符
记 B栈顶运算符为a1,当前运算符为a2(若a2为数字直接 a2->A )
1)若 a1>a2,a1->A,a2->B
1)若 a1<a2,a2->B;
2)若 a1>=a2
1.若a1>a2,a1->A;(只要该条件满足则一直执行,使得优先级高的运算符放在A中)
2.将高级运算符都排除后,要判断a1=a2 ?( 即是否为()相遇)
如果为左右括号的话就把做括号弹出,否则把a2->B。可以一直排除比它高级的运算法,但是只能抵消一个左括号
PS: a1>a2 表示 在此式中先算a1再算a2,a1与a2的关系在初始化中建立。
3.计算后缀表达式
从左往右扫描,遇到运算符则处理前两位数字

首先,将给定的字符串转为中缀表达式;使用List<String>保存表达式:程序代码如下

/**
* 将字符串转化为List
*
* @param str
* @return
*/
public ArrayList<String> getStringList(String str) {

ArrayList<String> result = new ArrayList<String>();

String num = "";

for (int i = 0; i < str.length(); i++) {

if (Character.isDigit(str.charAt(i)) || str.charAt(i) == ‘.‘) {

num = num + str.charAt(i);

} else {

if (num != "") {

result.add(num);

}

result.add(str.charAt(i) + "");

num = "";

}

}

if (num != "") {

result.add(num);
}

return result;

}

然后,将中缀表达式转变为后缀表达式,程序代码如下:

/**
* 将中缀表达式转化为后缀表达式
*
* @param inOrderList
* @return
*/
public ArrayList<String> getPostOrder(ArrayList<String> inOrderList) {

ArrayList<String> result = new ArrayList<String>();

Stack<String> stack = new Stack<String>();

stack.push("#");

for (int i = 0; i < inOrderList.size(); i++) {

if (Character.isDigit(inOrderList.get(i).charAt(0))) {

result.add(inOrderList.get(i));

} else {

switch (inOrderList.get(i).charAt(0)) {

case ‘(‘:

stack.push(inOrderList.get(i));

break;

case ‘)‘:

while (!stack.empty() && !stack.peek().equals("(")) {

result.add(stack.pop());
}

if (!stack.empty()) {
stack.pop();

}

break;

default:

while (!stack.empty() && !("#".equals(stack.peek()))
&& compare(stack.peek(), inOrderList.get(i))) {

result.add(stack.pop());

}

stack.push(inOrderList.get(i));

break;
}

}

}

while (!stack.empty() && !("#".equals(stack.peek()))) {

result.add(stack.pop());
}

return result;
}

其次,还得比较运算符的优先级,程序代码如下所示:

/**
* 比较运算符等级
*
* @param peek
* @param cur
* @return
*/
public static boolean compare(String peek, String cur) {

if ("*".equals(peek)
&& ("/".equals(cur) || "*".equals(cur) || "-".equals(cur) || "+"
.equals(cur))) {

return true;

} else if ("/".equals(peek)
&& ("/".equals(cur) || "*".equals(cur) || "-".equals(cur) || "+"
.equals(cur))) {

return true;

} else if ("+".equals(peek) && ("+".equals(cur) || "-".equals(cur))) {

return true;

} else if ("-".equals(peek) && ("+".equals(cur) || "-".equals(cur))) {

return true;

} else if ("#".equals(peek)) {

return true;
}

return false;

}

最后,计算表达式的值,程序代码如下:

/**
* 计算后缀表达式
*
* @param postOrder
* @return
*/
public Float calculate(ArrayList<String> postOrder) {

Stack<Float> stack = new Stack<Float>();
for (int i = 0; i < postOrder.size(); i++) {

if (Character.isDigit(postOrder.get(i).charAt(0))) {

stack.push(Float.valueOf(postOrder.get(i)));

} else {

Float back = (Float) stack.pop();

Float front = (Float) stack.pop();

float result = 0F;

switch (postOrder.get(i).charAt(0)) {

case ‘+‘:
result = front + back;

break;
case ‘-‘:
result = front - back;
break;
case ‘*‘:
result = front * back;
break;
case ‘/‘:
result = front / back;
break;
}

stack.push(result);
}
}

return stack.pop();

}

定义一个测试类,测试代码

public static void main(String[] args) {

EvaluateExpress exp = new EvaluateExpress();

String str = "24+(89-23*6)/3";

ArrayList<String> result = exp.getStringList(str);

System.out.print("中缀表达式:");

for (String s : result) {
System.out.print(s);
}

System.out.println("\n------------------");
ArrayList<String> postResult = exp.getPostOrder(result);
System.out.print("后缀表达式:");
for (String strs : postResult) {
System.out.print(strs);
}

System.out.println("\n-------------");
float calResult = exp.calculate(postResult);
System.out.println("计算结果为:" + calResult);

}

时间: 2024-12-16 17:10:08

基于Java语言的表达式计算的相关文章

基于Java语言构建区块链(一)—— 基本原型

引言 区块链技术是一项比人工智能更具革命性的技术,人工智能只是提高了人类的生产力,而区块链则将改变人类社会的生产关系,它将会颠覆我们人类社会现有的协作方式.了解和掌握区块链相关知识和技术,是我们每位开发人员必须要去做的事情,这样我们才能把握住这波时代趋势的红利. 本文将基于Java语言构建简化版的blockchain,来实现数字货币. 创建区块区块链是由包含交易信息的区块从后向前有序链接起来的数据结构.区块被从后向前有序地链接在这个链条里,每个区块都指向前一个区块.以比特币为例,每个区块主要包含

基于JAVA语言的多线程技术

1.简介 多线程技术属于操作系统范围内的知识: 进程与线程 可以这么理解,一个应用程序就是一个进程,在一个进程中包含至少一个线程:进程就是线程的容器,真正工作.处理任务的是线程. 进程是操作系统分配资源的基本单位:线程是操作系统进行调度,时间分配的基本单位: 进程由内核对象和地址空间两部分构成,内核对象就是一小块记录进程信息的内存,只允许操作系统访问:地址空间就是存放数据和程序的空间: 2.多线程运行机制 对于单个CPU,在每个时间点只能只能执行一个线程,多线程的实现是基于对时间片的轮回机制的,

基于Java的简易表达式解析工具(二)

之前简单的介绍了这个基于Java表达式解析工具,现在把代码分享给大家,希望帮助到有需要的人们,这个分享代码中依赖了一些其他的类,这些类大家可以根据自己的情况进行导入,无非就是写字符串处理工具类,日期处理的工具类什么的. 这个Java的表达式解析的工具只用了5个类,而且写得也很简单明了,相信有一些编程经验的可以看懂这些处理的逻辑代码. 1.第一个类:ExpressionNodeType(表达式各个字符节点的类型枚举类) public enum ExpressionNodeType { Unknow

基于JAVA语言的selenium测试基础总结

目录一.基本语句 1.循环控制(break,continue) 3.字符的替换(replace,repalceFirst,replaceAll,regex) 4.字符串的连接("+",append) 5.字符串的截取和分割(substring,split) 6.文件夹的创建与删除(mkdirs,delete) 7.文件的读写(BufferedWrite,BufferedReader) 8.系统时间的获取( ((Calendar.getInstance()).get(Calendar.Y

基于java语言简单版的学生信息系统

功能简介: a:可以对学生信息增删改查, b:每一种操作都是使用容器进行 c:使用自己写的工具类,可以实现多次调用,实现代码的复用,增加可读性 d:语法使用嵌套循环,一般使用while,swich..case,for 代码实现: //测试类 package com.xinboedu.www.test; public class TestSystem { public static void main(String[] args) { StudentSystem studentSystem = n

基于java语言的给cube添加custom view来实现权限控制

今天是农历2014年的最后一个工作日了,在这里提前祝大家新年快乐.羊年大吉!当然本人今天也拿出来点儿真东西,做为献给大家的新年礼物,依次共勉. 下文主要讲述的是使用Java代码来完成对cube基于部门维度创建custom view,实现角色级别的权限控制 第一部分:通用数据库设计 1:事实表(订单分析)--存放departkey关联部门 2:维度表(部门) 3:赋权表 role_id以及对应的role_name,来源于cognos cjap认证中的角色表depart_id以及对应的depart_

基于Java语言的MD5加密Base64转换方法

提供了基于MD5加密16位和32位的方法 1 import java.io.IOException; 2 import java.math.BigInteger; 3 import java.security.MessageDigest; 4 import java.security.NoSuchAlgorithmException; 5 import sun.misc.BASE64Decoder; 6 import sun.misc.BASE64Encoder; 7 /** 8 * <p>标

基于Java语言构建区块链(三)—— 持久化 &amp; 命令行

引言上一篇 文章我们实现了区块链的工作量证明机制(Pow),尽可能地实现了挖矿.但是距离真正的区块链应用还有很多重要的特性没有实现.今天我们来实现区块链数据的存储机制,将每次生成的区块链数据保存下来.有一点需要注意,区块链本质上是一款分布式的数据库,我们这里不实现"分布式",只聚焦于数据存储部分. 给大家推荐一个java内部学习群:725633148,进群找管理免费领取学习资料和视频.没有错就是免费领取!大佬小白都欢迎,大家一起学习共同进步! 数据库选择 到目前为止,我们的实现机制中还

基于JAVA语言的网络爬虫

Introduction: 这个小demo用于爬取淘宝网的相关链接. 首先从"www.taobao.com"这个url开始,手机页面上的所有url,然后存入toCrawList .当toCrawList不为空时,拿出一个url,把它存入数据集并且搜寻这个url上的所有链接充入toCrawList. 这是一个BFS过程. Framework: Code: 就网络爬虫来讲这个demo没有太多特别之处,只是根据项目需求,最大的爬取url数有个限制,因此效率上会相对的做出一些优化.另外为了防止