java 计算器

package Calculator;


import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;


public class Calculator {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Calculator calc = new Calculator();
boolean yn = true;
Double result;


while (yn) {
System.out.println("请输入需要计算式子:如-1.1+2*3(4*(-6+5))/(6(2+0.2)(7-3))= ");
String str = input.next();
/*
* if ("N".equals(str)) { System.out.println("谢谢使用!"); break; }
*/
// 计算处理
result = calc.prepareParam(str);
if (result != null) {
// 处理结果并打印
System.out.println("结果:"
+ MyUtils.formatResult(String.format("%." + MyUtils.RESULT_DECIMAL_MAX_LENGTH + "f", result)));
}
System.out.println("是否继续:y>继续,n>退出");
String string = input.next();
boolean b = true;
apk:while (b) {


if (string.equals("y")) {
yn = true;
break apk;
} else if (string.equals("n")) {
yn = false;
break apk;
} else {
b=true;
System.out.println("您输入的有误,从新输入:");
string = input.next();
}
}
}


}


/**
* @Title: PrepareParam
* @Desc: 准备计算的数据,符号
* @param str计算式
* @return 计算结果
*/
public Double prepareParam(String str) {
// 空值校验
if (null == str || "".equals(str)) {
return null;
}
// 长度校验
if (str.length() > MyUtils.FORMAT_MAX_LENGTH) {
System.out.println("表达式过长!");
return null;
}
// 预处理
str = str.replaceAll(" ", "");// 去空格
if ('-' == str.charAt(0)) {// 开头为负数,如-1,改为0-1
str = 0 + str;
}
// 校验格式
if (!MyUtils.checkFormat(str)) {
System.out.println("表达式错误!");
return null;
}
// 处理表达式,改为标准表达式
str = MyUtils.change2StandardFormat(str);
// 拆分字符和数字
String[] nums = str.split("[^.0-9]");
List<Double> numLst = new ArrayList();
for (int i = 0; i < nums.length; i++) {
if (!"".equals(nums[i])) {
numLst.add(Double.parseDouble(nums[i]));
}
}
String symStr = str.replaceAll("[.0-9]", "");
return doCalculate(symStr, numLst);
}


/**
* @Title: doCalculate
* @Desc: 计算
* @param symStr符号串
* @param numLst数字集合
* @return 计算结果
*/
public Double doCalculate(String symStr, List<Double> numLst) {
LinkedList<Character> symStack = new LinkedList<>();// 符号栈
LinkedList<Double> numStack = new LinkedList<>();// 数字栈
double result = 0;
int i = 0;// numLst的标志位
int j = 0;// symStr的标志位
char sym;// 符号
double num1, num2;// 符号前后两个数
while (symStack.isEmpty() || !(symStack.getLast() == '=' && symStr.charAt(j) == '=')) {// 形如:
// //
// =8=
// //
// 则退出循环,结果为8
if (symStack.isEmpty()) {
symStack.add('=');
numStack.add(numLst.get(i++));
}
if (MyUtils.symLvMap.get(symStr.charAt(j)) > MyUtils.symLvMap.get(symStack.getLast())) {// 比较符号优先级,若当前符号优先级大于前一个则压栈
if (symStr.charAt(j) == '(') {
symStack.add(symStr.charAt(j++));
continue;
}
numStack.add(numLst.get(i++));
symStack.add(symStr.charAt(j++));
} else {// 当前符号优先级小于等于前一个 符号的优先级
if (symStr.charAt(j) == ')' && symStack.getLast() == '(') {// 若()之间没有符号,则“(”出栈
j++;
symStack.removeLast();
continue;
}
if (symStack.getLast() == '(') {// “(”直接压栈
numStack.add(numLst.get(i++));
symStack.add(symStr.charAt(j++));
continue;
}
num2 = numStack.removeLast();
num1 = numStack.removeLast();
sym = symStack.removeLast();
switch (sym) {
case '+':
numStack.add(MyUtils.plus(num1, num2));
break;
case '-':
numStack.add(MyUtils.reduce(num1, num2));
break;
case '*':
numStack.add(MyUtils.multiply(num1, num2));
break;
case '/':
if (num2 == 0) {// 除数为0
System.out.println("存在除数为0");
return null;
}
numStack.add(MyUtils.divide(num1, num2));
break;
}
}
}
return numStack.removeLast();
}

}



package Calculator;


import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;


public class MyUtils {
public static final int FORMAT_MAX_LENGTH = 500;// 表达式最大长度限制
    public static final int RESULT_DECIMAL_MAX_LENGTH = 8;// 结果小数点最大长度限制
    public static final Map<Character, Integer> symLvMap = new HashMap<Character, Integer>();// 符号优先级map
    static {
        symLvMap.put('=', 0);
        symLvMap.put('-', 1);
        symLvMap.put('+', 1);
        symLvMap.put('*', 2);
        symLvMap.put('/', 2);
        symLvMap.put('(', 3);
        symLvMap.put(')', 1);


    }


    /**
     * @Title: checkFormat
     * @Desc: 检查表达式格式是否正确
     * @param str表达式
     * @return true表达式正确,false表达式错误
     */
    public static boolean checkFormat(String str) {
        // 校验是否以“=”结尾
        if ('=' != str.charAt(str.length() - 1)) {
            return false;
        }
        // 校验开头是否为数字或者“(”
        if (!(isCharNum(str.charAt(0)) || str.charAt(0) == '(')) {
            return false;
        }
        char c;
        // 校验
        for (int i = 1; i < str.length() - 1; i++) {
            c = str.charAt(i);
            if (!isCorrectChar(c)) {// 字符不合法
                return false;
            }
            if (!(isCharNum(c))) {
                if (c == '-' || c == '+' || c == '*' || c == '/') {
                    if (c == '-' && str.charAt(i - 1) == '(') {// 1*(-2+3)的情况
                        continue;
                    }
                    if (!(isCharNum(str.charAt(i - 1)) || str.charAt(i - 1) == ')')) {// 若符号前一个不是数字或者“)”时
                        return false;
                    }
                }
                if (c == '.') {
                    if (!isCharNum(str.charAt(i - 1)) || !isCharNum(str.charAt(i + 1))) {// 校验“.”的前后是否位数字
                        return false;
                    }
                }
            }
        }
        return isBracketCouple(str);// 校验括号是否配对
    }


    /**
     * @Title: change2StandardFormat
     * @Desc: 处理表达式格式为标准格式,如2(-1+2)(3+4)改为2*(0-1+2)*(3+4)
     * @param str
     * @return 标准表达式
     */
    public static String change2StandardFormat(String str) {
        StringBuilder sb = new StringBuilder();
        char c;
        for (int i = 0; i < str.length(); i++) {
            c = str.charAt(i);
            if (i != 0 && c == '(' && (isCharNum(str.charAt(i - 1)) || str.charAt(i - 1) == ')')) {
                sb.append("*(");
                continue;
            }
            if (c == '-' && str.charAt(i - 1) == '(') {
                sb.append("0-");
                continue;
            }
            sb.append(c);
        }
        return sb.toString();
    }


    /**
     * @Title: isBracketCouple
     * @Desc: 校验括号是否配对
     * @param str
     * @return 参数
     */
    public static boolean isBracketCouple(String str) {
        LinkedList<Character> stack = new LinkedList<>();
        for (char c : str.toCharArray()) {
            if (c == '(') {
                stack.add(c);
            } else if (c == ')') {
                if (stack.isEmpty()) {
                    return false;
                }
                stack.removeLast();
            }
        }
        if (stack.isEmpty()) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * @Title: formatResult
     * @Desc: 处理计算结果的显示
     * @param str计算结果
     * @return 规范的计算结果
     */
    public static String formatResult(String str) {
        String[] ss = str.split("\\.");
        if (Integer.parseInt(ss[1]) == 0) {
            return ss[0];// 整数
        }
        String s1 = new StringBuilder(ss[1]).reverse().toString();
        int start = 0;
        for (int i = 0; i < s1.length(); i++) {
            if (s1.charAt(i) != '0') {
                start = i;
                break;
            }
        }
        return ss[0] + "." + new StringBuilder(s1.substring(start, s1.length())).reverse();
    }


    /**
     * @Title: isCorrectChar
     * @Desc: 校验字符是否合法
     * @param c
     * @return 参数
     */
    public static boolean isCorrectChar(Character c) {
        if (('0' <= c && c <= '9') || c == '-' || c == '+' || c == '*' || c == '/' || c == '(' || c == ')'
                || c == '.') {
            return true;
        }
        return false;
    }


    /**
     * @Title: isCharNum
     * @Desc: 判断是否为数字
     * @param c
     * @return
     */
    public static boolean isCharNum(Character c) {
        if (c >= '0' && c <= '9') {
            return true;
        }
        return false;


    }


    /**
     * @Title: plus
     * @Desc: 加
     * @param num1
     * @param num2
     * @return 计算结果
     */
    public static double plus(double num1, double num2) {
        return num1 + num2;
    }


    /**
     * @Title: reduce
     * @Desc: 减
     * @param num1
     * @param num2
     * @return 计算结果
     */
    public static double reduce(double num1, double num2) {
        return num1 - num2;
    }


    /**
     * @Title: multiply
     * @Desc: 乘
     * @param num1
     * @param num2
     * @return 计算结果
     */
    public static double multiply(double num1, double num2) {
        return num1 * num2;


    }


    /**
     * @Title: divide
     * @Desc: 除
     * @param num1
     * @param num2
     * @return 计算结果
     */
    public static double divide(double num1, double num2) {
        return num1 / num2;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值