写安卓写了三年有余了吧!今天无聊,在网上看看安卓的计算器居然没有一个实现的好的,真实让人心寒啊!
闲着无聊,我也写了一个java实现计算器,代码简单易懂,稍微有那么点不好懂的我都写了详细的注释的!
那我就先说说我的思路吧!
/**
* 计算器算法
* @author Lxiang
* 思想:
* 把一个字符串表达式,拆分成两个集合,一个集合包含计算中的数,一个集合包含计算中的符号
* 1.把一个表达式中的运算子提取出来
* 2.把一个表达式中的数提取出来
* 3.遍历运算子集合,优先运算乘法和除法(遇到乘法除法的时候,移除运算子,并计算)
* 4.之后剩下的就是加法和减法,依次遍历计算
* 5.如果有括号的情况,递归调用
* 计算的核心思路
* 从运算子集合中取出一个运算子
* 在取出运算子的位置从运算参数的集合中的取出参与运算的两个数 参与运算的数是两个连续数
*/
那么,核心算法其实就很简单了,也就是一个递归的过程和一个四则运算,可谓so easy!
那么,废话不多说,上核心代码
/**
* 不带括弧的核心算法
* @param exp 表达式
* @return 结果
*/
public static double calc(String exp) {
//1.把一个表达式中的运算子提取出来
List<Character> operations = getOperation(exp);
//2.把一个表达式中的数提取出来
List<Double> numbers = getNumbers(exp);
//遍历计算(乘法和除法)
for (int i = 0; i < operations.size(); i++) {
//遍历获取运算子
char op = operations.get(i);
//如果这个运算子是乘法或者除法
if (op == '*' || op == '/') {
//移除这个运算子
Character remove = operations.remove(i);
//需要在同一个位置取出对应的运算数
Double double1 = numbers.remove(i);
//因为list的特性 移除了之后整个数据会向前移动一位 因此第二个数据就在当前的角标位置
Double double2 = numbers.remove(i);
//判断是乘法还是除法 做相应的运算
double1 = (remove == '*' ? double1*double2 : double1/double2);
//计算完成之后 还需要在同一个位置插入运算数
numbers.add(i,double1);
}
}
//遍历计算加法和减法
while (!operations.isEmpty()) {
//一次计算 所以每次都是第一个运算符
char op = operations.remove(0);
//需要在同一个位置取出对应的运算数
Double double1 = numbers.remove(0);
//因为list的特性 移除了之后整个数据会向前移动一位 因此第二个数据就在当前的角标位置
Double double2 = numbers.remove(0);
//判断是乘法还是除法 做相应的运算
double1 = (op == '-' ? double1-double2 : double1+double2);
//计算完成之后 还需要在同一个位置插入运算数
numbers.add(0,double1);
}
//计算完了以后 集合中还会剩下一个元素 就是结果
return numbers.get(0);
}
这样的话,在集合中留下的最后一个运算数就是结果了!
那么,来测试一下结果吧!
System.out.println(Calc.calculator("(-2.3*-3+32/(2*(-3+(-3))-3))*2+(3+5)"));
此处只贴出了没有括号的算法,源码中有贴出有括号的算法!