用java写一个大数计算的类_用Java写的一个实现大数计算器的类

为了练习一下Java编程,今天写了一个能进行大数计算的类,只需要调用本类的一个方法,以算数表达式为参数,方法就可返回计算结果。

import java.math.BigInteger;

import java.util.EmptyStackException;

import java.util.HashMap;

import java.util.Stack;

/*

* 该类实现对大值数进行简单计算的功能

* */

class BigNumCalculator {

private String input; //要计算的表达式

private String output;//结算结果

Stack operand;//操作数栈

Stack operator;//操作符栈

HashMap prect_map; //操作符和优先级之间的映射关系

/*

* 无参构造函数

* */

public BigNumCalculator() {

this.operand = new Stack();

this.operator = new Stack();

prect_map = new HashMap();

prect_map.put("+", new Integer(1));

prect_map.put("-", new Integer(1));

prect_map.put("*", new Integer(2));

prect_map.put("/", new Integer(2));

}

/*

* 对输入的表达式进行简单的检查。合法字符:数字、+、-、*、/、(、)之外是否还包含别的字符)

* 返回值:如果表达式不包含非合法字符,则返回true,否则返回false

* 调用本类函数:无

* */

private void check()throws ExpressionException {

if(!this.input.matches("[\\d\\+\\-\\*/()]*"))//用正则表达式检查表达式是否合法,如果不合法,抛出表达式不合法异常,不懂正则表达式的参考此处:点击打开链接

throw new ExpressionException("Expressions contain only numbers,+,-,*,/");

}

/*

* 函数功能:比较两个操作符的优先级

* 参数:要比较的两个操作符

* 返回值:如果1、第一个操作符优先级比第二个低,返回负值;

* 2、优先级相同,返回0;

* 3、第一个操作符比第二个操作符高,返回正值

* 调用本类函数:无

* */

private int compOperator(String op1, String op2) {

return this.prect_map.get(op1).intValue() - this.prect_map.get(op2).intValue();

}

/*

* 函数功能:将两个指定的大数对象,按指定的操作符进行运算,得出结果

* 参数:要计算的两个大数类对象,和字符串表示的操作符

* 返回值:返回一个大整数类对象,表示操作结果

* 调用本类函数:无

* */

private BigInteger compute(BigInteger bi1, BigInteger bi2, String operator) {

switch(operator.charAt(0)) {

case '+': return bi1.add(bi2);

case '-': return bi1.subtract(bi2);

case '*': return bi1.multiply(bi2);

case '/': return bi1.divide(bi2);

default: return null;

}

}

/*

* 函数功能:根据输入的表达式,计算出用字符串表示的结果

* 参数:一个String对象,表示要计算的表达式

* 返回值:一个String对象,表示结算得到的结果

* 异常抛出:如果表达式不合法,则抛出相应的异常

* 调用本类中的函数:check(),compOperator(),compute()

* */

public String calculate(String input) throws ExpressionException{

input = "(" + input + ")";//将传进来的表达式字符串赋值给类成员,之所以给表达式包上一层括号,上为了方便最后得到一个结果

this.input = input;

this.check(); //检查表达式是否合法

StringBuffer sb = new StringBuffer();//解析表达式时用来存储数字

for(int j = 0; j < input.length(); j ++) {

String tmp = "" + input.charAt(j);//将当前正解析的字符转化为字符串

if(tmp.matches("\\d")) {//当前解析的是数字

sb.append(tmp.charAt(0));

}

else if(tmp.charAt(0) == '(') {//当前解析的是'('

//(前面必定紧挨着操作符,所以不需要将操作数进行压栈,因为StringBuffer对象必为空

this.operator.push(tmp);

}

else if(tmp.matches("[\\+\\-\\*/]{1}")) {//当前解析的是+、-、*、/

//遇到操作符,将之前的字符串变换为一个大数,压入操作数栈中,并将存储数字的StringBuffer对象清空

BigInteger biTemp = new BigInteger(sb.toString());

this.operand.push(biTemp);

sb.delete(0, sb.length());

/*执行操作符栈中优先级低于或等于当前操作符的操作

* 首先从操作符栈中弹出一个操作符,

* 然后从操作数栈中弹出两个操作数

* 执行操作后将结果压入操作数栈中

* */

while(!this.operator.empty()) {

String topOperator = this.operator.pop();

if(topOperator.equals("(")) {//如果遇到"(",停止处理

this.operator.push(topOperator);

break;

}

if(this.compOperator(tmp, topOperator) <= 0) {//如果栈中的操作符优先级比当前解析的操作符优先级高或相等

BigInteger bi1 = this.operand.pop();

BigInteger bi2 = this.operand.pop();

this.operand.push(this.compute(bi1, bi2, topOperator));

}

else {//如果栈中的操作符比当前解析的操作符优先级低

this.operator.push(topOperator);//将弹出的操作符重新压入操作符栈

break;

}

}

this.operator.push(tmp);//将当前操作符压入操作符栈

}

else {//如果当前解析的右括号)

//将之前的字符串变换为一个大数,压入操作数栈中,并将存储数字的StringBuffer对象清空

BigInteger biTemp = new BigInteger(sb.toString());

this.operand.push(biTemp);

sb.delete(0, sb.length());

try {

String topOperator = this.operator.pop();

while(!topOperator.equals("(")) {

BigInteger bi1 = this.operand.pop();

BigInteger bi2 = this.operand.pop();

this.operand.push(this.compute(bi1, bi2, topOperator));

topOperator = this.operator.pop();

}

}

catch(EmptyStackException e) {

throw new ExpressionException();

}

}

}

if(!this.operator.empty() || this.operand.size() != 1)

throw new ExpressionException();

this.output = this.operand.pop().toString();

return this.output;

}

}

上面的类中引用了自己编写的一个异常类:

/*

* 自己编写的一个异常类,如果表达式不合法,则抛出该异常

* */

class ExpressionException extends Exception {

/**

*

*/

private static final long serialVersionUID = 1L;

public ExpressionException(String msg) {

super(msg);

}

public ExpressionException() {

super("parsing fault");

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值