zoukankan      html  css  js  c++  java
  • 栈实现综合计算器

    思路分析:

     代码实现:

    package stack;
    
    public class Calculator {
    public static void main(String[] args) {
        String expression="7+2*60-4";//如何处理多位数的问题?
        //创建两个栈,一个数栈,一个符号栈
        ArrayStack2 numStack= new ArrayStack2(10);
        ArrayStack2 operStack = new ArrayStack2(10);
        //定义相关变量
        int index=0;//用于扫描
        int num1=0;
        int num2=0;
        int oper=0;
        int res=0;
        char ch=' ';//将每次扫描得到char保存到ch
        String keepNum="";
        //开始while循环扫描expression
        while(true) {
            //以此得到expression的每一个字符
            ch=expression.substring(index,index+1).charAt(0);
            //判断ch
            if(operStack.isOper(ch)) {
                //判断当前符号栈是否为空
                if(!operStack.isEmpty()) {
                    //如果符号栈有操作符,就进行比较,如果当前的操作符优先级小于或者等于栈中的操作
                    if(operStack.priority(ch)<=operStack.priority(operStack.peek())){
                    num1=numStack.pop();
                    num2=numStack.pop();
                    oper=operStack.pop();
                    res=numStack.cal(num1, num2, oper);
                    //把运算结果入数栈
                    numStack.push(res);
                    //把当前的操作符入符号栈
                    operStack.push(ch);
                    }else {
                        //直接入栈
                        operStack.push(ch);
                    }
                }else {
                    //如果为空,直接入符号栈
                    operStack.push(ch);
                    }
        }else {
            //如果是数栈,则直接入数栈
            //当处理多位数时。不能发现是一个数就立即入栈
            //在处理时,需要向expression的表达式的index后再看一位,如果是数,就进行扫描,如果是·符号才入栈
            //因此我们需要定义一个变量字符串,用于拼接
            keepNum+=ch;
            //如果ch已经是expression最后一位
            if(index==expression.length()-1) {
                numStack.push(Integer.parseInt(keepNum));
            }else {
            //判断下一个字符是不是数字
            if(operStack.isOper(expression.substring(index+1,index+2).charAt(0))) {
                //如果后一位是运算符,则入栈
                numStack.push(Integer.parseInt(keepNum));
                keepNum="";
            }
    //        numStack.push(ch-48);
            }
            }
            //让index+1,并判断是否扫描到expression最后
            index++;
            if(index>=expression.length()) {
                break;
            }
        }
        while(true) {
            //如果符号栈为空,则计算到最后的结果
            if(operStack.isEmpty()) {
                break;
            }num1=numStack.pop();
            num2=numStack.pop();
            oper=operStack.pop();
            res=numStack.cal(num1, num2, oper);
            numStack.push(res);
        }
        System.out.printf("表达式%s=%d",expression,numStack.pop());
    }
    }
    //先创建一个栈,需要扩展功能
    class ArrayStack2{
        private int maxSize;
        private int[] stack;//数组模拟栈,数据就放在该数组
        private int top=-1;
        //构造器
        public ArrayStack2(int maxSize) {
            this.maxSize=maxSize;
            stack=new int[this.maxSize];
        }
        //增加一个方法,可以返回当前栈顶的值但是不pop
        public int peek() {
            return stack[top];
        }
        //栈满
        public boolean isFull() {
            return top==maxSize-1;
        }
        //栈空
        public boolean isEmpty() {
            return top==-1;
        }
        //入栈
        public void push (int value) {
            //先判断栈是否满
            if(isFull()) {
                System.out.println("栈满");
                return;
            }
            top++;
            stack[top]=value;
        }
        //出栈
        public int pop() {
            if(isEmpty()) {
                //抛异常处理
                throw new RuntimeException( "栈空,没有数据");
            }
            int value=stack[top];
            top--;
            return value;
        }
        //遍历栈,需要从栈顶开始显示数据
        public void list() {
            if(isEmpty()) {
                System.out.println("栈空,没有数据");
                return;
            }
            for(int i=top;i>=0;i--) {
                System.out.printf("stack[%d]=%d
    ",i,stack[i]);
            }
        }
        //返回运算符的优先级,优先级是程序员来确定的,优先级使用数字表示,数字越大,优先级越高
        public int priority(int oper) {
            if(oper=='*'||oper=='/') {
                return 1;
            }else if(oper=='+'||oper=='-') {
                return 0;
            }else {
                return -1;//假定目前表达式只有加减乘除
            }
            }
        //判断是不是运算符
        public boolean isOper(char val) {
            return val=='+'||val=='-'||val=='*'||val=='/';
        }
        //计算方法
        public int cal(int num1,int num2,int oper) {
            int res=0;//用于存放计算结果
            switch (oper) {
            case '+':
                res=num1+num2;
                break;
            case '-':
                res=num2-num1;//注意顺序
                break;
            case '*':
                res=num1*num2;
                break;
            case '/':
                res=num2/num1;
                break;
    
            default:
                break;
            }
            return res;
        }
    }
  • 相关阅读:
    存储过程简介
    微信公众号开发之授权获取用户信息
    微信公众号开发之自定义菜单
    微信公众号开发之如何实现消息交互
    VS2012创建ATL工程及使用MFC测试COM组件
    Regsvr32 在64位机器上的用法(转载)
    模块加载失败 请确保该二进制文件在指定的路径中 找不到指定的模块(转载)
    [内核驱动] miniFilter 内核层与应用程序通信
    [内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问
    InstallShield 2015 生成单个EXE包和 MSI包
  • 原文地址:https://www.cnblogs.com/boogie-xy/p/11688256.html
Copyright © 2011-2022 走看看