首先拿一个例子来说说吧,输入一串类似于“487.24*454.2-545/5454”这样的算式组成的字符串来进行计算精确结果
首先说说思路,当得到是一串由数字和运算符组成的字符串时,首先要拆分成两个LinkList<>链表,一个用来储存大数字组比如487.24,一个纯标点符号;
拆分是关键,我们自己写一个迭代器类来实现。最后进行计算,我先把代码写出来,然后再一行行的进行解释,有些方法就不解释了
package day1501day;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Formula3 {
private String f;
public Formula3(String f) {
this.f = f;
}//这是构造函数,用来取输入的字符串并赋值给成员变量f
public class DeDaiQi {//自己写一个迭代器的类
int from;//设置一个下标
Matcher m = Pattern.compile("\\d+(\\.+\\d+)?|[+\\-*/]").matcher(f);//把传过来的数进行按照正则表达式来寻找拆分
public String next() {
m.find(from);//在指定下标后寻找并取出赋给s
String s = m.group();
from = m.end();//下标右移到下一个拆分对象
return s;//返回找到的子串
}
public boolean hasNext() {
return from < f.length();//用下标值和f的长度进行比较来确定有没有找完
}
}
public BigDecimal eval(){//计算的方法
//定义两个链表,一个存大数字,一个纯运算符
LinkedList<BigDecimal> list1= new LinkedList<>();
LinkedList<String> list2=new LinkedList<>();
DeDaiQi d= new DeDaiQi();//启用迭代器
while(d.hasNext()){//当f被查找完毕时才结束
String s=d.next();//找到第一个赋给s
if(s.matches("\\d+(\\.\\d+)?")){//用正则表达式来判段是数字还是运算符
BigDecimal x=new BigDecimal(s);
list1.add(x);
}
else if(s.matches("[+\\-]")){//如果是加减直接存到2链表中
list2.add(s);
}
else{//如果是*/由于运算的优先级,直接将存的上一个和运算符的后一个进行计算
//然后将计算的返回值继续存在1链表(具体计算后面会写)
BigDecimal a = list1.removeLast();
BigDecimal b = new BigDecimal(d.next());
BigDecimal e=jisuan(a,s,b);
list1.add(e);
}
}
while (list2.size()!=0){//当都拆分完毕和计算乘除完毕后进行最后的加减运算
//将链表1 的投两个值都移出来赋给a,b
BigDecimal a=list1.removeFirst();
BigDecimal b=list1.removeFirst();
//字符也拿出来
String s = list2.removeFirst();
//传给jishuan方法
BigDecimal e= jisuan(a, s, b);
//将结果再存进链表1的第一个位置
list1.addFirst(e);
}
//计算完所有的值时链表1只剩下一个值,就是结果了,
return list1.get(0);
}
//计算方法
private BigDecimal jisuan(BigDecimal a, String s, BigDecimal b) {
//将传过来的值赋给s1和s2
BigDecimal s1=a;
BigDecimal s2=b;
BigDecimal s3=new BigDecimal(0);
//用switch来进行相应的运算
switch (s.charAt(0)){
//由于运算符就一位,所以用charAt(0)将String类型转为char类型并//用case进行选择运算
case ‘+’:
s3=s1.add(s2);//调用大数字的方法加
break;
case ‘-‘:
s3=s1.subtract(s2);//调用大数字的方法进行减
break;
case’*’:
s3=s1.multiply(s2);//同上
break;
case’/’:
s3=s1.divide(s2, 5,BigDecimal.ROUND_HALF_UP);
//由于除有可能会有无限循环的,就调用大数字的方法进行舍入运算
break;
}
return s3;//将结果返回过去
}
}
然后是测试类
package day1501day;
import java.math.BigDecimal;
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
System.out.println(“请输入算式”);
String s= new Scanner(System.in).nextLine();
Formula3 f= new Formula3(s);
BigDecimal d=f.eval();
System.out.println(d);
}
}
第一次写,别介意了