Java 进行四则运算

四则运算的基础原理是将中缀表达式转换成为后缀表达式。然后进行计算。

转换思路和原理,可以参考将中缀表达式转化为后缀表达式

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.regex.Pattern;

public class Arithmetic {
	//操作符stack
	private Stack<String> operator = new Stack<String>();
	//后缀表达式
	private List<String> postFix = new ArrayList<String>();

	private Pattern operatorPattern = Pattern.compile("[\\d\\.]");
	private Pattern arithmeticPattern = Pattern.compile("[\\(\\)\\+\\-\\*\\/]");

	//将中缀表达式换为后缀表达式
	public void parse(String s) {
		s = replace(s);
		int j = 0;
		for (int i = 0; i < s.length(); i++) {
			String temp = s.substring(i, i + 1);
			if (operatorPattern.matcher(temp).matches()) {
				continue;
			}
			if (arithmeticPattern.matcher(temp).matches()) {
				j = process(j, i, s, temp);
			} else if (" ".equals(temp)) {
				return;
			}
		}
		if (j < s.length()) {
			postFix.add(s.substring(j, s.length()));
		}
		while (!this.operator.isEmpty()) {
			postFix.add(operator.pop());
		}
	}

	private String replace(String s) {
		return s.replaceAll("\\s", "");
	}

	private int process(int startIndex, int currentIndex, String str, String word) {
		if (startIndex != currentIndex) {
			postFix.add(str.substring(startIndex, currentIndex));
		}
		addOperator(word);
		startIndex = currentIndex + 1;
		if (startIndex > str.length()) {
			startIndex = str.length();
		}
		return startIndex;
	}

	public void addOperator(String operator) {
		if ("(".equals(operator)) {

		} else if(")".equals(operator)) {
			while (!this.operator.isEmpty()) {
				String temp = this.operator.pop();
				if ("(".equals(temp)) {
					break;
				} else {
					postFix.add(temp);
				}

			}
			return;
		} else if (!this.operator.isEmpty()) {
			while(!this.operator.isEmpty()) {
				String temp = this.operator.peek();
				if (needPop(temp, operator)) {
					this.postFix.add(this.operator.pop());
				} else {
					break;
				}
			}
		}
		this.operator.add(operator);
	}

	public boolean needPop(String inStackTop, String current) {
		return getLevel(current.charAt(0)) <= getLevel(inStackTop.charAt(0));
	}

	public int getLevel(char operator) {
		switch (operator) {
		case '+':
			return 1;
		case '-':
			return 1;
		case '*':
			return 2;
		case '/':
			return 2;
		default:
			return -1;
		}
	}

	public BigDecimal compute() {
		Stack<BigDecimal> stack = new Stack<BigDecimal>();
		for (int i=0; i < this.postFix.size(); i++) {
			if (arithmeticPattern.matcher(postFix.get(i)).matches()) {
				BigDecimal bd2 = stack.pop();
				BigDecimal bd1 = stack.pop();
				BigDecimal temp = compute(postFix.get(i).charAt(0), bd1, bd2);
				stack.add(temp);
			} else {
				stack.add(new BigDecimal(postFix.get(i)));
			}
		}
		return stack.pop();
	}

	private BigDecimal compute(char operator, BigDecimal bd1, BigDecimal bd2) {
		switch (operator) {
		case '+':
			return bd1.add(bd2);
		case '-':
			return bd1.subtract(bd2);
		case '*':
			return bd1.multiply(bd2);
		case '/':
			return bd1.divide(bd2);//应当使用bd1.divide(divisor, scale, roundingMode);
		default:
			return null;
		}
	}

	public static void main(String[] args) {
		Arithmetic arithmetic = new Arithmetic();
		arithmetic.parse("9+(3-1)*3+10/2");
		System.out.println(arithmetic.postFix);
		System.out.println(arithmetic.compute());

		arithmetic = new Arithmetic();
		arithmetic.parse("9+(3-1)*3+10/2+1000-200-(100+5-9/3)");
		System.out.println(arithmetic.postFix);
		System.out.println(arithmetic.compute());

		arithmetic = new Arithmetic();
		arithmetic.parse("9 + (3 - 1) * 3 + 10 / 2 + 1000 - 200 - ( 100 + 5 - 9 / 3)");
		System.out.println(arithmetic.postFix);
		System.out.println(arithmetic.compute());
	}
}

Java 进行四则运算

时间: 2024-10-23 05:01:49

Java 进行四则运算的相关文章

Java中四则运算的那些坑

使用Java开发多年,感觉自己的水平也在不断提升,但是被Java狂虐却从来都没变过,而且任何一个Java的小角落,都能把我虐的体无完肤,但是无奈要靠Java吃饭,还得恬着脸继续使用下去.说说最近遇到的问题,则于新工作属于互联网金融,所以里面涉及到了大量的资金计算,资金计算对数字要求的比较严谨,作为一个粗心而又自大的Java程序员,一直没把这个当回事儿,于是又被Java吊打一遍.下面记录一下Java中四则运算的一些需要注意的小坑. 数学计算,免不了要想到 int long double 这种数据类

java小学生四则运算带面板版 但我不知道为什么同类变量却进不了动作监听中去

---恢复内容开始--- 1 package yun; 2 import java.util.*; 3 import java.awt.*; 4 import java.awt.event.ActionEvent; 5 import java.awt.event.ActionListener; 6 7 import javax.swing.*; 8 public class number extends JFrame{ 9 10 /** 11 * 作者:范铭祥 12 * 功能:一个简单的小学生四

Java高精度四则运算(无括号限制)

package cn.skyatom.common; import java.math.BigDecimal; import java.util.regex.Matcher; import java.util.regex.Pattern; /**  * 基础四则运算  *  * @author ZWK  */ public class Arithmetic {     private static String getUUID() {         return java.util.UUID.

Java实现 四则运算生成 (戴国权 &amp; 关绍华)

  GitHub仓库:https://github.com/BiuBiuBangBoom/mathcreate   项目要求: 题目:实现一个自动生成小学四则运算题目的命令行程序说明: 说明: 自然数:0, 1, 2, -. 真分数:1/2, 1/3, 2/3, 1/4, 1'1/2, -. 运算符:+, ?, ×, ÷. 括号:(, ). 等号:=. 分隔符:空格(用于四则运算符和等号前后). 算术表达式: e = n | e1 + e2 | e1 ? e2 | e1 × e2 | e1 ÷

java重构四则运算

package 重构四则运算; import java.io.IOException; public class Test { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub Test t=new Test(); t.comeTrue(); } private void comeTrue() throws IOException { // TODO Aut

java生成四则运算

要求:使用C或Java语言完成一个自动生成四则运算试题的程序 软件基本功能如下. 自动生成10道100以内的2个操作数的四则运算算式(+ - * /),要求运算结果也在100以内 剔除重复算式.2+3 和 2+3 是重复算式,2+3 和 3+2 不属于重复算式 题目数量可定制 相关参数可控制 是否包含乘法和除法 操作数数值范围可控 操作数是否含负数 生成的运算题存储到外部文件result.txt中 1. 需求分析 ? 某小学里,老师让家长每天出30道加减法题目给孩子做.于是,想写一个小程序完成这

【转】Java精确四则运算

/** * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入. */ public class Arith { // 默认除法运算精度 private static final int DEF_DIV_SCALE = 10; // 这个类不能实例化 private Arith() { } /** * 提供精确的加法运算. * * @param v1 * 被加数 * @param v2 * 加数 * @return 两个参数的和 */ p

Java实现四则运算

GitHub:https://github.com/Wamelon/operations 组员:黄锐斌,张正浩 1题目:实现一个自动生成小学四则运算题目的命令行程序. 2说明: 自然数:0, 1, 2, -. 真分数:1/2, 1/3, 2/3, 1/4, 1'1/2, -. 运算符:+, ?, ×, ÷. 括号:(, ). 等号:=. 分隔符:空格(用于四则运算符和等号前后). 算术表达式: e = n | e1 + e2 | e1 ? e2 | e1 × e2 | e1 ÷ e2 | (e)

结对编程Java实现四则运算(林伯浩 刘育明)

GIthub项目地址:https://github.com/3116004696/ruanjiangongcheng/tree/master/Myapp 项目要求: 实现一个自动生成小学四则运算题目的命令行程序. 1. 使用 -n 参数控制生成题目的个数.(实现) 2. 使用 -r 参数控制题目中数值(自然数.真分数和真分数分母)的范围.(未实现真分数运算) 3. 生成的题目中计算过程不能产生负数.(实现) 4. 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数.(未实现)