输入表达式计算表达式的值(java)

问题描述:

输入一个计算表达式,计算该表达式的值。表达式复杂度分为两级:第一级:加减乘除;
第二级:包含sin、cos、tgn、sqrt、exp、pow函数

*解决思路

1.设置两个栈,一个用于存放操作数,一个用于存放运算符

private static Stack<Double> vals = new Stack<Double>();
    private static Stack<Character> ops = new Stack<Character>();

2.基于后缀表达式设计,从左往右遍历字符数组,遇到数字入栈,遇到’('以及一些特殊函数预算符入栈。这里sin用’s’代替入栈,cos用’c’代替……

if(i + 4 <= ch.length){
                String str1 = new String(ch,i,3);
                String str2 = new String(ch,i,4);
                if(str1.equals("sin")) {
                    ops.push(ch[i]);//s表示sin
                    i+=3;
                }else if(str1.equals("cos")){
                    ops.push(ch[i]);//c表示cos
                    i+=3;
                }else if(str1.equals("tan") || str1.equals("tgn")){
                    ops.push(ch[i]);//t表示tan函数
                    i+=3;
                }else if(str1.equals("exp")){
                    ops.push(ch[i]);//e表示指数函数
                    i+=3;
                }else if(str2.equals("sqrt")){
                    ops.push('q');//q表示开方
                    i +=4;
                }
            }           

3.若扫描到数字,则数字入栈(这里特别注意负数的处理,以及浮点数的处理)

			if(ch[i] == '-' && (vals.empty() || ops.lastElement() == '(')){
                isNegative = true;//判断是否为负数
                i ++;
            }
            if ((ch[i] >= '0' && ch[i] <= '9') || ch[i] == '.') {
                double val = 0;
                double temp = 1;
                boolean byPoint = false;
                while ((ch[i] >= '0' && ch[i] <= '9') || ch[i] == '.') {
                    if (ch[i] == '.') {
                        i++;
                        byPoint = true;
                        temp = 10;
                        continue;
                    }
                    if (byPoint) {
                        int x = (int) ch[i] - 48;
                        val += ((double) x) / temp;
                        temp = temp * 10;
                        i++;

                    } else {
                        int x = (int) ch[i] - 48;
                        val = val*10 + x;
                        i++;
                    }
                }
                if(isNegative) val = -1*val;
                vals.push(val);
                continue;
            }

4.扫描到运算符,则弹出栈里更高级或者同级的运算符,这里特别注意特殊函数的运算级别最高,而且遇见特殊函数只弹出一个操作数。

else if(ch[i] == '+' || ch[i] == '-' || ch[i] == '*'|| ch[i] == '/'||ch[i] == '^'){
                char t = ch[i];
                char c;
                switch (t){
                    case '+':
                    case '-':
                        c = ops.pop();
                       while (c != '(' && c != '#'){
                           double r;
                           double l;
                           if(c == '+'){
                               r = vals.pop();
                               l = vals.pop();
                               vals.push(l + r);
                           }else if(c == '-'){
                               r = vals.pop();
                               l = vals.pop();
                               vals.push(l - r);
                           }else if(c == '*'){
                               r = vals.pop();
                               l = vals.pop();
                               vals.push(l*r);
                           }else if(c == '/'){
                               r = vals.pop();
                               l = vals.pop();
                               vals.push(l/r);
                           }else if(c == '^'){
                               r = vals.pop();
                               l = vals.pop();
                               vals.push(pow(l,r));
                           }else if(c == 'q'){
                               r = vals.pop();
                               vals.push(sqrt(r));
                           } else if (c == 's') {
                               r = vals.pop();
                               vals.push(sin(r));
                           }else if(c == 'c'){
                               r = vals.pop();
                               vals.push(cos(r));
                           }else if(c == 't'){
                               r = vals.pop();
                               vals.push(tan(r));
                           }else if(c == 'e'){
                               r = vals.pop();
                               vals.push(exp(r));
                           }
                           c = ops.pop();


                       }
                       ops.push(c);
                       ops.push(ch[i]);
                       i++;
                       break;
                    case '*':
                    case '/':
                        c = ops.pop();
                        while (c != '(' && c != '#' && c != '+' && c != '-'){
                            double r;
                            double l;
                            if(c == '*'){
                                r = vals.pop();
                                l = vals.pop();
                                vals.push(l*r);
                            }else if(c == '/'){
                                r = vals.pop();
                                l = vals.pop();
                                vals.push(l/r);
                            }else if(c == '^'){
                                r = vals.pop();
                                l = vals.pop();
                                vals.push(pow(l,r));
                            }else if(c == 'q'){
                                r = vals.pop();
                                vals.push(sqrt(r));
                            } else if (c == 's') {
                                r = vals.pop();
                                vals.push(sin(r));
                            }else if(c == 'c'){
                                r = vals.pop();
                                vals.push(cos(r));
                            }else if(c == 't'){
                                r = vals.pop();
                                vals.push(tan(r));
                            }else if(c == 'e'){
                                r = vals.pop();
                                vals.push(exp(r));
                            }
                            c = ops.pop();
                        }
                        ops.push(c);
                        ops.push(ch[i]);
                        i++;
                        break;
                    case '^':
                        ops.push('^');
                        i ++;
                        break;
                }
                continue;
            }

遇到左括号直接入栈

else if(ch[i] == '('){
                ops.push(ch[i]);
                i ++;
                continue;
            }

遇到右括号,拼命弹出运算符和操作数,不停地算直到栈中遇到’#’(结束标志)或左括号

else if(ch[i] == ')' || ch[i] == '\0'){
                char c = ops.pop();
                while(c != '(' && c != '#'){
                    double r;
                    double l;
                    if(c == '+'){
                        r = vals.pop();
                        l = vals.pop();
                        vals.push(l + r);
                    }else if(c == '-'){
                        r = vals.pop();
                        l = vals.pop();
                        vals.push(l - r);
                    }else if(c == '*'){
                        r = vals.pop();
                        l = vals.pop();
                        vals.push(l*r);
                    }else if(c == '/'){
                        r = vals.pop();
                        l = vals.pop();
                        vals.push(l/r);
                    }else if(c == '^'){
                        r = vals.pop();
                        l = vals.pop();
                        vals.push(pow(l,r));
                    }else if(c == 'q'){
                        r = vals.pop();
                        vals.push(sqrt(r));
                    } else if (c == 's') {
                        r = vals.pop();
                        vals.push(sin(r));
                    }else if(c == 'c'){
                        r = vals.pop();
                        vals.push(cos(r));
                    }else if(c == 't'){
                        r = vals.pop();
                        vals.push(tan(r));
                    }else if(c == 'e'){
                        r = vals.pop();
                        vals.push(exp(r));
                    }

                    c = ops.pop();
                }
                i++;
                continue;

完整代码:

package Homework;

import java.util.Scanner;
import java.util.Stack;

import static java.lang.Math.*;

public class calculator2 {
    private static Stack<Double> vals = new Stack<Double>();
    private static Stack<Character> ops = new Stack<Character>();
    private static void calculate(String str){
        char[] ch = (str+"\0").toCharArray();
        ops.push('#');
        int i = 0;
        while(i < ch.length) {
            boolean isNegative = false;
            if(i + 4 <= ch.length){
                String str1 = new String(ch,i,3);
                String str2 = new String(ch,i,4);
                if(str1.equals("sin")) {
                    ops.push(ch[i]);//s表示sin
                    i+=3;
                }else if(str1.equals("cos")){
                    ops.push(ch[i]);//c表示cos
                    i+=3;
                }else if(str1.equals("tan") || str1.equals("tgn")){
                    ops.push(ch[i]);//t表示tan函数
                    i+=3;
                }else if(str1.equals("exp")){
                    ops.push(ch[i]);//e表示指数函数
                    i+=3;
                }else if(str2.equals("sqrt")){
                    ops.push('q');//q表示开方
                    i +=4;
                }
            }
            if(ch[i] == '-' && (vals.empty() || ops.lastElement() == '(')){
                isNegative = true;
                i ++;
            }
            if ((ch[i] >= '0' && ch[i] <= '9') || ch[i] == '.') {
                double val = 0;
                double temp = 1;
                boolean byPoint = false;
                while ((ch[i] >= '0' && ch[i] <= '9') || ch[i] == '.') {
                    if (ch[i] == '.') {
                        i++;
                        byPoint = true;
                        temp = 10;
                        continue;
                    }
                    if (byPoint) {
                        int x = (int) ch[i] - 48;
                        val += ((double) x) / temp;
                        temp = temp * 10;
                        i++;

                    } else {
                        int x = (int) ch[i] - 48;
                        val = val*10 + x;
                        i++;
                    }
                }
                if(isNegative) val = -1*val;
                vals.push(val);
                continue;
            }else if(ch[i] == '+' || ch[i] == '-' || ch[i] == '*'|| ch[i] == '/'||ch[i] == '^'){
                char t = ch[i];
                char c;
                switch (t){
                    case '+':
                    case '-':
                        c = ops.pop();
                       while (c != '(' && c != '#'){
                           double r;
                           double l;
                           if(c == '+'){
                               r = vals.pop();
                               l = vals.pop();
                               vals.push(l + r);
                           }else if(c == '-'){
                               r = vals.pop();
                               l = vals.pop();
                               vals.push(l - r);
                           }else if(c == '*'){
                               r = vals.pop();
                               l = vals.pop();
                               vals.push(l*r);
                           }else if(c == '/'){
                               r = vals.pop();
                               l = vals.pop();
                               vals.push(l/r);
                           }else if(c == '^'){
                               r = vals.pop();
                               l = vals.pop();
                               vals.push(pow(l,r));
                           }else if(c == 'q'){
                               r = vals.pop();
                               vals.push(sqrt(r));
                           } else if (c == 's') {
                               r = vals.pop();
                               vals.push(sin(r));
                           }else if(c == 'c'){
                               r = vals.pop();
                               vals.push(cos(r));
                           }else if(c == 't'){
                               r = vals.pop();
                               vals.push(tan(r));
                           }else if(c == 'e'){
                               r = vals.pop();
                               vals.push(exp(r));
                           }
                           c = ops.pop();


                       }
                       ops.push(c);
                       ops.push(ch[i]);
                       i++;
                       break;
                    case '*':
                    case '/':
                        c = ops.pop();
                        while (c != '(' && c != '#' && c != '+' && c != '-'){
                            double r;
                            double l;
                            if(c == '*'){
                                r = vals.pop();
                                l = vals.pop();
                                vals.push(l*r);
                            }else if(c == '/'){
                                r = vals.pop();
                                l = vals.pop();
                                vals.push(l/r);
                            }else if(c == '^'){
                                r = vals.pop();
                                l = vals.pop();
                                vals.push(pow(l,r));
                            }else if(c == 'q'){
                                r = vals.pop();
                                vals.push(sqrt(r));
                            } else if (c == 's') {
                                r = vals.pop();
                                vals.push(sin(r));
                            }else if(c == 'c'){
                                r = vals.pop();
                                vals.push(cos(r));
                            }else if(c == 't'){
                                r = vals.pop();
                                vals.push(tan(r));
                            }else if(c == 'e'){
                                r = vals.pop();
                                vals.push(exp(r));
                            }
                            c = ops.pop();
                        }
                        ops.push(c);
                        ops.push(ch[i]);
                        i++;
                        break;
                    case '^':
                        ops.push('^');
                        i ++;
                        break;
                }
                continue;
            }else if(ch[i] == '('){
                ops.push(ch[i]);
                i ++;
                continue;
            }else if(ch[i] == ')' || ch[i] == '\0'){
                char c = ops.pop();
                while(c != '(' && c != '#'){
                    double r;
                    double l;
                    if(c == '+'){
                        r = vals.pop();
                        l = vals.pop();
                        vals.push(l + r);
                    }else if(c == '-'){
                        r = vals.pop();
                        l = vals.pop();
                        vals.push(l - r);
                    }else if(c == '*'){
                        r = vals.pop();
                        l = vals.pop();
                        vals.push(l*r);
                    }else if(c == '/'){
                        r = vals.pop();
                        l = vals.pop();
                        vals.push(l/r);
                    }else if(c == '^'){
                        r = vals.pop();
                        l = vals.pop();
                        vals.push(pow(l,r));
                    }else if(c == 'q'){
                        r = vals.pop();
                        vals.push(sqrt(r));
                    } else if (c == 's') {
                        r = vals.pop();
                        vals.push(sin(r));
                    }else if(c == 'c'){
                        r = vals.pop();
                        vals.push(cos(r));
                    }else if(c == 't'){
                        r = vals.pop();
                        vals.push(tan(r));
                    }else if(c == 'e'){
                        r = vals.pop();
                        vals.push(exp(r));
                    }

                    c = ops.pop();
                }
                i++;
                continue;
            }else{
                System.out.println("输入异常!");
                break;
            }
        }
        System.out.println(vals.pop());

    }

    public static void main(String[] args) {
        while (true){
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入算数表达式:");
            String str = scanner.next();
            if(str.equals("#")){
                break;
            }

            try{
                calculate(str);
            }catch (Exception e){
                System.out.println("输入异常!");
            }
        }

    }
}

运行示范:

请输入算数表达式:
sin3.14
0.0015926529164868282
请输入算数表达式:
exp(1)*2+(-3)
2.43656365691809
请输入算数表达式:
#

Process finished with exit code 0

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值