一个科学计算器的面向对象实现,完成多年的心愿

当年java课程的大作业是写一个计算器,我花了两个多星期总算完成了,但是却只写了一个类,代码达1500多行,压根纯粹没用到java的面向对象思想,现在想想还有点惭愧

最近想起了这个事情,于是想抽空写一个完整的面向对象的科学计算器,完成以前未了的心愿

稍微花了点时间整理了一下思路:

1.首先得将表达式分为操作数和运算符,这里用正则即可

private String		regex	= "\\^|(\\d+\\.\\d+)|(\\d+)|(\\+)|(-)|(\\*)|(/)|(\\()|(\\))|sin|cos|tan|\\!";
	

当然我只是写了一部分运算符,其他的类似

2.运算符和操作数统一都继承了Item类,而所有的运算符类又继承了Operator类,其实所有运算符可以用一个类来表示,但是为了更明确的突出面向对象,一种运算符一个类,并且有优先级和操作数个数等属性

3.本来四则运算是可以转成逆波兰式计算的,但是这里还包括了三角函数,阶乘,乘方等非四则运算的运算符,标准的逆波兰式显然不适合,于是重新设计了思路如下:

 1)首先去括号,获取最里层的括号,计算里面的无括号表达式,得到结果后替换这一部分,然后递归直到去掉所有的括号,最后剩下一个无括号的表达式,跟之前去括号时调用同样的计算方法。

 2)无括号的表达式采用这样的计算方式,遍历表达式,获取最高优先级的运算符,并根据运算符获取前后的操作数(三角函数取后面一个,阶乘取前面一个,其他前后各取一个),然后根据Operator类里定义的计算方法获得结果,然后替换计算过的部分,递归进行下一步计算,直到整个表达式只剩下一个操作数,那么这就是最后的计算结果。

计算无括号表达式的方法

private Operand calculate(List<Item> subList) {
		if (subList.size() == 0) {
			return null;
		} else if (subList.size() == 1 && subList.get(0) instanceof Operand) {
			return (Operand) subList.get(0);
		} else {
			Operator operator = null;
			int index = -1;
			int priority = -1;
			for (int i = 0; i < subList.size(); i++) {
				Item item = subList.get(i);
				if (item instanceof Operator) {
					if (((Operator) item).getPriority() > priority) {
						operator = (Operator) item;
						index = i;
						priority = operator.getPriority();
					}
				}
			}
			if (operator instanceof Factorial) {
				operator.setOperand1((Operand) subList.get(index - 1));
				subList.add(index, operator.getResult());
			} else {
				if (operator.getOperandCount() == 1) {
					operator.setOperand1((Operand) subList.get(index + 1));
					subList.add(index, operator.getResult());
				} else if (operator.getOperandCount() == 2) {
					operator.setOperand1((Operand) subList.get(index - 1));
					operator.setOperand2((Operand) subList.get(index + 1));
					subList.add(index, operator.getResult());
				}
			}
			subList.remove(operator);
			subList.remove(operator.getOperand1());
			subList.remove(operator.getOperand2());
			return calculate(subList);
		}
	}


 3) 其中要考虑一些细节问题,比如表达式不正确会导致数组越界,比如有些地方可以省略乘号等,整个计算器的设计思想算是完成了,而且添加其他的运算符也是很容易的



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值