字符串计算器

输入为中缀表达式字符串,计算结果。表达式可包含四则运算和括号。

实现步骤

1.将输入的中缀表达式转为后缀表达式
2.对后缀表达式求值

转化规则:
1.将数字直接添加到后缀表达式中
2.操作符栈为空或为扫描到左括号直接压入符号栈
3.当前操作符优先级大于栈顶优先级,直接压入符号栈
4.操作符优先级小于或等于栈顶,弹出所有大于或等于当前操作符的栈顶添加到后缀表达式中,该操作符入栈
5.扫描到右括号,从符号栈弹出元素,添加到后缀表达式,直到遇到左括号,弹出左括号,不添加到后缀表达式
6.扫描结束后,把符号栈的元素弹出,添加到后缀表达式
优先级:
+ 和 - 为同优先级, * 和 /同优先级, + -优先级小于 * /

用Java实现将中缀表达式转为后缀表达式如下

    /**
     @param exp 中缀表达式
     */
    public static String postfix (String exp) {
        StringBuilder postfix = new StringBuilder();
        Stack<Character> opt = new Stack();
        char [] c = exp.toCharArray();
        //遍历中缀表达式,请查看上面的规则
        for (int i=0;i<c.length;i++) {
            if (isNum(c[i])){
                postfix.append(c[i]);
                int flag = i;
                //如果当前字符为数字且下一位不数字,或当前数字已是中缀表达式字符串最后一位,在多位数后添加" "来分隔
                if ( (i<c.length-1&&!isNum(c[flag+1]))|| i == c.length-1)
                    postfix.append(" ");
                continue;
            }
            if (c[i]=='('||c[i]=='*'||c[i]=='/'){
                opt.push(c[i]);
                continue;
            }
            if (c[i]==')'){
                while ((!opt.isEmpty())) {
                    if (opt.peek()=='('){
                        opt.pop();
                        continue;
                    }
                    postfix.append(opt.pop());
                }
                continue;
            }
            if (c[i]=='+'||c[i]=='-'){
                while ((!opt.isEmpty())&&opt.peek()!='('){
                    postfix.append(opt.pop());
                }
                opt.push(c[i]);
                continue;
            }
        }

        //当遍历完中缀表达式,把此时符号栈的元素弹出,添加到后缀表达式
        while (!opt.isEmpty()){
            postfix.append(opt.pop());
        }
        return postfix.toString();
    }
    //判断是否为数字的方法
    public static boolean isNum(char c){
        return c>=48 && c<=57;
    }

测试

input:15-3*(12-9)
output:15 3 12 9 -*-

转为后缀表达式后要对其进行求值,规则如下:
扫描后缀表达式,遇到数字,将其压入操作数栈中;遇到操作符。从操作数栈中弹出2个操作数,根据当前操作符的运算规则进行运算。

用Java实现计算功能:

/**
     @param expression 后缀表达式
     */
    public static void compute(String expression) {
        Stack<Integer> num = new Stack<>();
        StringBuilder  sb = new StringBuilder();
        char[] c = expression.toCharArray();
        for (int i = 0;i< c.length;i++) {
            if (isNum(c[i])) {
                sb.append(c[i]);
                //如果当前字符已经是表达式字符串最后一位,直接放入操作数栈
                if (i+1 == c.length) {
                    num.push(Integer.parseInt(sb.toString()));
                    continue;
                }
                //判断是否为多位数,如果当前字符下一位为设置的" "标记,就截取到当前字符
                if (c[i+1]==" ".charAt(0)) {
                    num.push(Integer.parseInt(sb.toString()));
                    sb.delete(0,sb.length());
                    continue;
                }
                continue;
            }
            if (c[i]=='+') {
                num.push(num.pop()+num.pop());
            }
            if (c[i] == '-') {
                int num1 = num.pop();
                int num2 = num.pop();
                num.push(num2-num1);
            }
            if (c[i] == '*') {
                num.push(num.pop()*num.pop());
            }
            if (c[i] == '/') {
                int num1 = num.pop();
                int num2 = num.pop();
                num.push(num2/num1);
            }
        }
        //扫面完后缀表达式,操作数栈只剩下一个元素,就是计算的结果
        System.out.println("result is :"+num.pop());
    }
输入:15-3*(12-9)
后缀表达式为:15 3 12 9 -*-
result is :6
欢迎小伙伴们一起交流讨论 !

你可能感兴趣的:(数据结构与算法)