Java计算器核心算法代码实现
作者:sdr_zd 发布时间:2022-03-18 05:38:55
标签:java,计算器,核心,算法
在进行一个表达式的计算时,先将表达式分割成数字和字符串然后利用出入栈将分割后的表达式进行中缀转后缀,再将后缀表达式进行计算得到结果(思想在上一篇写过)现在贴下Java语言的代码实现。(学习Java时间不长所以可能会有很多不足的地方,我会改进也欢迎大神可以给我一些意见和建议~谢谢啦)
我将这部分分成三个方法完成功能,并在getResult
方法调用(getResult方法被主方法调用)
private String getResult(String str) {
//分割
String[] Str = segment(str);
//中缀转后缀
String newStr = infToSuf(Str);
//后缀计算
String result = sufToRes(newStr);
return sufToRes(result);
}
1.字符串分割,为避免在TextView上显示带空格删除时不方便而且显示屏就那么大占地方,录入时的字符串中没有空格然后就手动分割了
private static String[] segment(String str) {
String[] exp = new String[str.length()+1];
//找最近的索引并截取字符串
int l = str.length();
for(int i = 0;i < l+1;i++) {
int index;
int[] ind = new int[6];
ind[0] = str.indexOf('+');
ind[1] = str.indexOf('-');
ind[2] = str.indexOf('*');
ind[3] = str.indexOf('/');
ind[4] = str.indexOf('(');
ind[5] = str.indexOf(')');
if(ind[1] == 0) {
Arrays.sort(ind);
int t;
for(t = 0;t <6;t++) {
if(ind[t] >= 0)
break;
}
int r = ind[t+1];
exp[i] = str.substring(0,r);
i++;
exp[i] = str.substring(r,r+1);
str = str.substring(r+1);
}else if(((ind[1]-ind[4]) == 1) && (ind[4]==0)) {
Arrays.sort(ind);
int t ;
for(t = 0;t <6;t++) {
if(ind[t] >= 0)
break;
}
int r = ind[t+1];
exp[i] = str.substring(0,1);
i++;
exp[i] = str.substring(1,r+2);
i++;
exp[i] = str.substring(r+2,r+3);
str = str.substring(r+3);
}else {
Arrays.sort(ind);
int t;
for(t = 0;t <6;t++) {
if(ind[t] >= 0)
break;
}
if(t==6)
break;
index = ind[t];
if(index!=0) {
exp[i] = str.substring(0,index);
i++;
}
exp[i] = str.substring(index,index+1);
str = str.substring(index+1);
}
}
int j = 0;
int k = 0;
for(; exp[j]!=null ;j++){}
if(!exp[j-1].equals(")")) {
exp[j]=str;
str = "";
k = j;
}else {
k = j-1;
}
String[] expp = new String[k+1];
for(int t = 0; t < k+1;t++) {
expp[t] = exp[t];
}
return expp;
//System.out.println("分割的字符串:");
}
2.中缀转后缀
private static String infToSuf(String[] exp) {
String newStrs = "";
//初始化栈
Stack<String> stack = new Stack<>();
/*
判断并放入后缀表达式中:
for循环遍历整个str进行判断
循环结束若栈不为空全部出栈
*/
int l = exp.length;
for(int i = 0; i < l; i++) {
if ((stack.empty()) && (exp[i].equals("+") || exp[i].equals("-") || exp[i].equals("*") || exp[i].equals("/"))) {
stack.push(exp[i]);
} else if (exp[i].equals("(")) {
stack.push(exp[i]);
} else if (exp[i].equals("*") || exp[i].equals("/")) {
while (stack.peek().equals("*") || stack.peek().equals("/")) {
newStrs = newStrs.concat(stack.pop()+" ");
if(stack.isEmpty()) {
break;
}
}
stack.push(exp[i]);
} else if (exp[i].equals("+") || exp[i].equals("-")) {
while (!(stack.isEmpty())&&((stack.peek()).equals("*") || (stack.peek()).equals("/") || (stack.peek()).equals("+") || (stack.peek()).equals("-"))) {
newStrs = newStrs.concat(stack.pop()+" ");
if(stack.isEmpty()) {
break;
}
}
stack.push(exp[i]);
} else if (exp[i].equals(")")) {
int t = stack.search("(");
for (int k = 1; k < t; k++) {
newStrs = newStrs.concat(stack.pop()+" ");
}
String tstr = stack.pop();
} else {
newStrs = newStrs.concat(exp[i]+ " ");
}
}
while (!stack.empty()) {
if (!stack.peek().equals("(") || !stack.peek().equals(")")) {
newStrs = newStrs.concat(stack.pop()+" ");
} else if (stack.peek().equals("(") || stack.peek().equals(")")) {
String tstr = stack.pop();
}
}
// System.out.println("后缀:"+newStrs);
return newStrs;
}
3.后缀的计算
private static String sufToRes(String sufStr) {
String[] exp = sufStr.split(" ");
Stack<String> stack = new Stack<>();
String Res = "";
for(int i = 0;i < exp.length; i++) {
if(!exp[i].equals("+") && !exp[i].equals("-") && !exp[i].equals("*") && !exp[i].equals("/")){
stack.push(exp[i]);
}else if(exp[i].equals("+")) {
BigDecimal b2 = new BigDecimal(stack.pop());
BigDecimal b1 = new BigDecimal(stack.pop());
BigDecimal b3 = b1.add(b2);
stack.push(b3.toString());
}else if(exp[i].equals("-")) {
BigDecimal b2 = new BigDecimal(stack.pop());
BigDecimal b1 = new BigDecimal(stack.pop());
BigDecimal b3 = b1.subtract(b2);
stack.push(b3.toString());
}else if(exp[i].equals("*")) {
BigDecimal b2 = new BigDecimal(stack.pop());
BigDecimal b1 = new BigDecimal(stack.pop());
BigDecimal b3 = new BigDecimal(0);
if(b1.compareTo(BigDecimal.ZERO)== 0|| b2.compareTo(BigDecimal.ZERO) == 0) {
b3 = BigDecimal.ZERO;
}else {
b3 = b1.multiply(b2);
}
stack.push(b3.toString());
}else if(exp[i].equals("/")){
BigDecimal b2 = new BigDecimal(stack.pop());
BigDecimal b1 = new BigDecimal(stack.pop());
BigDecimal b3 = new BigDecimal(0);
double d1 = b1.doubleValue();
double d2 = b2.doubleValue();
if(d1%d2 == 0){
b3 = (b1.divide(b2));
stack.push(b3.toString());
}else {
b3 = b1.divide(b2,10, RoundingMode.HALF_UP);
stack.push(b3.toString());
}
}
}
Res = stack.pop();
boolean flag = false;
for (int m = 0; m < Res.length() - 1;m++) {
if(Res.charAt(m) == '.'){
flag = true;
}
}
if(flag) {
for(int m = Res.length()-1;m >= 0;m--) {
if(Res.charAt(m) == '0'){
}else {
Res = Res.substring(0,m+1);
break;
}
}
if(Res.charAt(Res.length()-1) == '.') {
Res = Res.substring(0,Res.length()-1);
}
}
return Res;
}
来源:https://blog.csdn.net/sdr_zd/article/details/52135924


猜你喜欢
- 项目背景我们开发过程中会碰到这样一类问题,就是数据层或三方接口返回的Bean对象需要转换重新装换一下我们需要的对象。我们通常的做法就是通过g
- 泛型类泛型类封装不是特定于具体数据类型的操作。泛型类最常用于集合,如链接列表、哈希表、堆栈、队列、树等。像从集合中添加和移除项这样的操作都以
- 本文实例讲述了Java设计模式之 * 模式。分享给大家供大家参考,具体如下: * 模式有三个要素——事件源、事件对象、 * 。事件源:顾名思
- 有时候我们需要实现这样的场景,类似进入开发者模式,即多次点击后执行操作。首先我们先看一个方法:System提供的一个静态方法arraycop
- 下面是每隔一段时间就执行某个操作,直到关闭定时操作:final Handler handler = new Handler();
- 本文实例讲述了Android使用ViewFlipper和GestrueDetector共同实现滑屏效果。分享给大家供大家参考,具体如下:关于
- 当我们在做前后端分离的开发时,在使用fetch交换数据的时候,提示Access-Control-Allow-Origin跨域问题,解决方案跟
- SpringBoot实现单文件上传功能,供大家参考,具体内容如下架构为springboot+thymeleaf,采用ajax方式提交1. 页
- 前言Groovy 是一种基于 JVM 的动态语言,与 Java 语言紧密集成,可以很方便地在 Java 项目中使用。Groovy 有着简洁的
- 定义jdk8发布新特性中,lambda是一大亮点之一。lambda表达式能够简化我们对数据的操作,减少代码量,大大提升我们的开发效率。Lam
- 本文实例讲述了C#多线程学习之使用线程池进行多线程的自动管理。分享给大家供大家参考。具体如下:在多线程的程序中,经常会出现两种情况:一种情况
- 目录Set接口概述HashSet实现类1、HashSet 具有以下特点:2、HashSet 集合判断两个元素相等的标准3、向HashSet中
- using System;using System.Collections;using System.Text;using Sy
- 基于Java swing+MySQL实现学生信息管理系统:主要实现JDBC对学生信息进行增删改查,应付一般课设足矣,分享给大家。(由于篇幅原
- 前言爱美之心人皆有之,在 unix 和 linux 命令行环境下工作的闷骚程序员们可能也觉得命令行太单调了,而是他们就发明了在命令行下采用
- 一、布局文件part.xml:<RelativeLayout xmlns:android="http://schemas.a
- 1. 数据构造索引2个文档到 hotel 索引中:PUT /hotel/_doc/1{ "title": &
- 宏定义与预处理命令预处理阶段:处理宏定义与预处理命令;编译期:检查代码,分析语法、语义等,最后生成.o或.obj文件;链接期:链接所有的.o
- java 配置MyEclipse Maven环境虽然我的大部分项目已经迁到Idea上去了,但是在写部分小的测试程序的时候还是习惯
- java 遍历listpackage com.tiandy.core.rest;import java.util.ArrayList;imp