zoukankan      html  css  js  c++  java
  • 高级计算器[Java版]

    import java.util.Scanner;

    /*
     * time:        2012年11月17日 11:34:10
     * content:     高级计算器
     * author:      覃唐弢
     * example:
     * 请输入计算表达式:1.2*{2.2-2/[3-(34-32)+2.3]+2.2}+2.3
      *  1.2*{2.2-2/[3-(34-32)+2.3]+2.2}+2.3=6.852727272727273
     * */

    public class Counter {
        public static void main(String[] args) {
            String expreStr = null;
            System.out.print("请输入计算表达式:");
            Scanner in = new Scanner(System.in);
            expreStr = in.next();
            Expression expr = new Expression(expreStr);
            double result = expr.start();
            System.out.println(expreStr+"="+result);
        }
    }

    //表达式处理类
    class Expression{
        private String expreStr="";
        private String temp = "";
        private int index = 0; //截取字符的下标位置
        private int len= 0 ;//表达式长度
        private double num1,num2,result;
        private char oper;
        private OperStack operStack = new OperStack(); //操作符栈
        private NumStack numStack  = new NumStack(); //操作数栈
        public Expression(String expreStr){
            this.expreStr = expreStr;
            this.len = this.expreStr.length();
        }
        
        //主运算
        public double start(){
            while(index<len){
                //判断一个数的最前面的位 不能是小数点 .
                if(this.isOper(this.getNextChar())==-1){
                    System.err.println("小数点不能在一个数的最前面,如[.123]");
                    System.exit(0);
                }
                temp+=this.truncate();
                char c = temp.toString().toCharArray()[0];    
                //是操作符 入操作符栈
                if(isOper(c)>0){
                    //是空 则直接入栈
                    if(this.operStack.isEmpty()){
                        this.operStack.push(c);
                    }else{
                        //当前 操作符是-+/*就去判断优先级  否则直接入栈
                        if(isOper(c)==1){
                            //如果栈顶是 ( 则直接入栈  1{-,+}  2{*, /}
                            if(this.operStack.priority(this.operStack.getTop())!=0){
                                //判断优先级
                                //1.1小于等于  栈顶操作符   ---> 计算 完 后  再入栈
                                //继续判断当前操作符 和 栈顶操作符的优先级
                                while(!this.operStack.isEmpty()&&this.operStack.priority(c)<=this.operStack.priority(this.operStack.getTop())){
                                    this.operation();
                                }
                            }
                        }else if(isOper(c)==22){ // 是 ) 则运算 ( ) 之间的
                        
                            //取完后 则计算 栈中剩余的操作符
                            while(!this.operStack.isEmpty() && isOper(this.operStack.getTop())==1){
                                this.operation();
                            }
                            //此时 把 操作符栈顶 的 ( -->出栈
                            this.operStack.pop();
                        }else if(isOper(c)==33){ // 是 ] 则运算 [ ] 之间的
                            //取完后 则计算 栈中剩余的操作符
                            while(!this.operStack.isEmpty() && isOper(this.operStack.getTop())==1){
                                this.operation();
                            }
                            //此时 把 操作符栈顶 的 [ -->出栈
                            this.operStack.pop();
                        }else if(isOper(c)==44){ // 是 } 则运算 { } 之间的
                            //取完后 则计算 栈中剩余的操作符
                            while(!this.operStack.isEmpty() && isOper(this.operStack.getTop())==1){
                                this.operation();
                            }
                            //此时 把 操作符栈顶 的 { -->出栈
                            this.operStack.pop();
                        }
                        //1.2 大于 栈顶操作符   ---> 入栈
                        if(isOper(c)<=4)
                            this.operStack.push(c);
                    }
                }else{
                //是操作数 入操作数栈
                    int isManyPoint = 0;
                    //应该继续判断下一个字符 是否也为数字
                    while(index<len && (this.isOper(this.getNextChar())==0 || this.isOper(this.getNextChar())==-1)){
                    //是数字
                        if(this.isOper(this.getNextChar())==-1){
                            isManyPoint++;
                        }
                        if(isManyPoint>=2){ //如果一个数中有多个小数点 则退出
                            System.err.println("一个数不能有多个小数点,如[12.23.23]");
                            System.exit(0);
                        }
                        temp+=this.truncate();
                    }
                    try{
                        this.numStack.push(Double.parseDouble(temp));
                    } catch (Exception e) {
                        System.err.println("表达式输入不正确!!");
                        return 0;
                    }
                }
                temp="";//清空
            }
            
            //取完后 则计算 栈中剩余的操作符
            while(!this.operStack.isEmpty()){
                this.operation();
            }
            //操作数 此时 只有一个元素 即结果
            return this.numStack.pop();
        }
        
        //取出操作数栈顶两个数  和 操作负  并运算  把结果放入操作数栈
        public void operation(){
            oper = this.operStack.pop();
            num1 = this.numStack.pop();
            num2 = this.numStack.pop();
            result = this.numStack.operation(num1, oper, num2);
            //计算完后 把结果放入 操作数栈顶
            this.numStack.push(result);
        }
        
        //取得字符串[操作符、操作数]
        public String truncate(){
            return this.expreStr.substring(index++, index);
        }
        
        //如果当前是数字 则获取下一个是否也为数字  12
        public char getNextChar(){
            String temp = this.expreStr.substring(index, index+1);
            char c = temp.toCharArray()[0];    
            return c;
        }
        
        //判断是否为操作符
        public int isOper(char oper){
            switch(oper){
                case '-':
                case '+':
                case '/':
                case '*':
                    return 1;
                case '(':
                    return 2;
                case '[':
                    return 3;
                case '{':
                    return 4;
                case ')':
                    return 22;
                case ']':
                    return 33;
                case '}':
                    return 44;
                case '.':
                    return -1;
                default: //是数字
                    return 0;
            }
        }
    }

    //操作符栈
    class OperStack{
        private char operStack[] = new char[100];  
        private int index = 0;
        //放入操作符
        public void push(char oper){
            this.operStack[index++] = oper;
        }
        //弹出栈顶操作符
        public char pop(){
            return this.operStack[--index];
        }
        //取得栈顶操作符
        public char getTop(){
            return this.operStack[index-1];
        }
        //判断是否为空
        public boolean isEmpty(){
            if(index<=0)
                return true;
            return false;
        }
        //比较操作符的优先级
        public int priority(char oper){
            switch(oper){
                case '-':
                case '+':
                    return 1;
                case '/':
                case '*':
                    return 2;
                default:
                    return 0;
            }
        }
        
    }
    //操作数栈
    class NumStack{
        private double numStack[] = new double[100];
        private int index = 0;
        //放入操作符
        public void push(double num){
            this.numStack[index++] = num;
        }
        //弹出栈顶操作数
        public double pop(){
            return this.numStack[--index];
        }
        //取得栈顶操作数
        public double getTop(){
            return this.numStack[index-1];
        }
        //判断是否为空
        public boolean isEmpty(){
            if(index<=0)
                return true;
            return false;
        }
        //运算
        public double operation(double num1, char oper, double num2){
                switch(oper){
                    case '-':
                        return num2-num1;
                    case '+':
                        return num2+num1;
                    case '/':
                        return num2/num1;
                    case '*':        
                        return num2*num1;
                    default:
                        return 0;
                }
        }
    }

  • 相关阅读:
    LuoguP4463 [集训队互测2012] calc DP+拉格朗日插值
    一些图的计数
    redis补充1之为什么要用 Redis/为什么要用缓存?
    redis补充4之Redis 和 Memcached 的区别和共同点
    redis补充3之为什么要有分布式缓存?/为什么不直接用本地缓存?
    redis补充2之简单说说有哪些本地缓存解决方案?
    1_java语言概述-注释与API文档等
    1_java语言概述-开发环境搭建
    weblogic 2021.4.20 季度补丁
    mysql source输出记录日志
  • 原文地址:https://www.cnblogs.com/qintangtao/p/2774029.html
Copyright © 2011-2022 走看看