用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<BigInteger> operand;//操作数栈
	Stack<String> operator;//操作符栈
	HashMap<String, Integer> prect_map; //操作符和优先级之间的映射关系
	
	/*
	 * 无参构造函数
	 * */
	public BigNumCalculator() {
		this.operand = new Stack<BigInteger>();
		this.operator = new Stack<String>();	
		prect_map = new HashMap<String, Integer>();
		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");
	}
}


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

上一篇:(转)Could not create the view: An unexpected exception was thrown. 电脑突然断电,myeclipse非正常关闭,出现错误


下一篇:Recovery模式下的文本显示