带括号的四则运算

    xiaoxiao2021-03-25  184

    带括号的四则运算

    public class CaculatorDemo {

    public static void main(String[] args) { String exp = "-3+6*-2-8/-4*2";//-11 String exp2 = "-3+(9+8+(8-4)/2)*2";//35 //double result = calc(exp); double result = calcKuohao(exp2); System.out.println(result); result = dkuohao(exp2); System.out.println(result); } /** * 带括号的四则运算 * @param exp * @return */ public static double calcKuohao(String exp){ //找最后一个左括号的下标,没找到就返回-1 int left = exp.lastIndexOf('('); if (left == -1) { //说明表达式无括号 return calc(exp); }else { //找与它相对应的右括号的下标 int right = exp.indexOf(')', left); //找到相对应的右括号之后,取出括号中的表达式 String str = exp.substring(left + 1, right); //对str做无括号四则运算 double d = calc(str); //拼接 exp = exp.substring(0, left) + d + exp.substring(right + 1); //递归去括号 return calcKuohao(exp); } } /** * 不带括号的四则运算 * @param exp * @return */ public static double calc(String exp){ double result = 0; //将负号转换成@符号 exp = fu2At(exp); //提取数字集合 List<Double> nums = getNums(exp); //提取运算符集合 List<Character> opts = getOpts(exp); //先乘除 //遍历运算符集合,如果是*/就取出来 for (int i = 0; i < opts.size(); i++) { char c = opts.get(i); if (c == '*' || c == '/') { opts.remove(i);//移除该运算符 //从数字集合的i的位置取出第一个数 double d1 = nums.remove(i); //再从数字集合的i的位置取出第二个数 double d2 = nums.remove(i); //判断运算符到底是乘号还是除号 if (c == '*') { d1 *= d2; }else { d1 /= d2; } //将运算结果,放回数字集合的i的位置 nums.add(i, d1); //为了避免i+1位置的乘除号被跳过。因为取出一个符号之后,后面的符号就会往前移动。 i --; } } //for循环结束后,表示乘除法做完了,只剩下加减法,opts里面只有+-号 //后加减,一直到所有运算符都被移除 while(!opts.isEmpty()){ //从运算符集合的0的位置取出运算符 char opt = opts.remove(0); //从数字集合的0的位置取出第一个数 double d1 = nums.remove(0); //从数字集合的0的位置取出第二个数 double d2 = nums.remove(0); if (opt == '+') { d1 += d2; }else { d1 -= d2; } //将运算结果放回到数字集合的0的位置 nums.add(0, d1); } //运算结束后,数字集合0的位置的值就是运算结果。 result = nums.get(0); //后加减 return result; } /** * 提取运算符集合 * @param exp * @return */ private static List<Character> getOpts(String exp) { //定义一个集合来,存储运算符 List<Character> opts = new ArrayList<>(); //用来分隔字符串的api StringTokenizer sTokenizer = new StringTokenizer(exp, "0123456789.@"); while(sTokenizer.hasMoreElements()){ String strs = sTokenizer.nextElement().toString(); opts.add(strs.charAt(0)); } return opts; } /** * 提取数字集合 * @param exp * @return */ private static List<Double> getNums(String exp) { //定义一个集合来存储数字 List<Double> nums = new ArrayList<>(); StringTokenizer sTokenizer = new StringTokenizer(exp, "+-*/"); while (sTokenizer.hasMoreElements()) { String str = sTokenizer.nextElement().toString(); //判断str中是否包含@,如果包含,则要将@符号转换成-。 if (str.charAt(0) == '@') { //将@符号转换成-号 str = "-" + str.substring(1); } //String要转换成Double类型 double d = Double.parseDouble(str); nums.add(d); } return nums; } /** * 将负号转换成@符号 * @param exp * @return */ private static String fu2At(String exp) { //先遍历字符串 for (int i = 0; i < exp.length(); i++) { char c = exp.charAt(i); if (c == '-') { //如果c是第零个 if (i == 0) { //一定表示负号 exp = "@" + exp.substring(1); }else { //如果不是0的位置 //判断c前面的一个字符是否是运算符 char prev = exp.charAt(i - 1); if (prev == '+' || prev == '-' || prev == '*' || prev == '/') { //说明c一定是表示负号 exp = exp.substring(0, i) + "@" + exp.substring(i + 1); } } } } return exp; }

    /*上述是基本小括号的运算, 下面2个方法是对中括号,大括号的增加*/

    private static Double dkuohao(String exp) { int indexStart = exp.lastIndexOf('{'); if(indexStart >= 0){ int indexEnd = exp.indexOf('}',indexStart); String temp = exp.substring(indexStart+1,indexEnd); double d = zkuohao(temp); exp = exp.substring(0,indexStart)+d+exp.substring(indexEnd+1); return dkuohao(exp); }else{ return zkuohao(exp); } } private static Double zkuohao(String exp) { int indexStart = exp.lastIndexOf('['); if(indexStart >= 0){ int indexEnd = exp.indexOf(']',indexStart); String temp = exp.substring(indexStart+1,indexEnd); double d = calcKuohao(temp); exp = exp.substring(0,indexStart)+d+exp.substring(indexEnd+1); System.out.println(exp); return zkuohao(exp); }else{ return calcKuohao(exp); } }

    }

    转载请注明原文地址: https://ju.6miu.com/read-2230.html

    最新回复(0)