• 数据结构之中缀表达式实现计算器


    栈还是用的上一篇的数组模拟栈,并在此之上增加了

    判断是否是一个运算符的方法

    获取运算符的优先级方法

    计算结果方法

    查看栈顶元素的方法

    四个方法,具体代码如下:

    package com.ebiz.stack;
    
    /**
     * @author YHj
     * @create 2019-07-20 14:20
     * 数组模拟栈
     */
    
    public class ArrayStack {
    
        private  int maxSize;
        private  int [] arr;  //数组模拟栈   
        private  int top = -1;
    
        //构造方法,初始化数组
        public ArrayStack(int maxSize) {
            this.maxSize=maxSize;
            this.arr = new int[maxSize];
        }
    
        //验证栈满
        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++;
            arr[top]=value;
        }
    
        //出栈
        public int pop(){
            if(isEmpty()){
                throw new RuntimeException("栈已空");
            }
            int value=arr[top];
            top--;
            return value;
        }
    
        //遍历栈
        public void list(){
            if (isEmpty()){
                throw new RuntimeException("栈为空");
            }
            while (true){
                if (isEmpty()){
                    System.out.println("栈为空");
                    break;
                }
                System.out.printf("出站元素为%d%n",arr[top]);
                top--;
            }
        }
    
        //返回运算符的优先级  优先级用数字表示
        //数字越大,代表优先级越高
        // *或者/  优先级为1
        // +或者-  优先级为0
        // -1 代表运算符为问题运算符
        public int priority(int operator){
            if ('*' == operator || '/' == operator){
                return 1;
            }else if ('+' == operator || '-' == operator){
                return 0;
            }else{
                return -1;
            }
        }
    
        //判断是否为一个运算符
        public boolean isOperator(char operator){
            return operator == '+' || operator == '-' || operator == '*' || operator == '/';
        }
    
        //计算方法
        public int calculator(int num01,int num02,int operator){
            //用于存放计算结果
            int result=0;
            switch (operator){
                case '+':
                    result = num01+num02;
                    break;
                case '-':
                    result = num02-num01;
                    break;
                case '*':
                    result = num01*num02;
                    break;
                case  '/':
                    result = num02/num01;
                    break;
                 default:
                     break;
            }
            return result;
        }
    
    
        //获取符号栈的栈顶符号,并不是真正取出该元素
        public int peek() {
            return arr[top];
        }
    }

    下面给出测试,中缀表达式提前给定好,只涉及到了两位数,对于小括号还有小数点后面会将中缀转为后缀,便于计算

    package com.ebiz.stack;
    
    /**
     * @author YHj
     * @create 2019-07-22 11:04
     * 栈模拟计算器  中缀表达式
     */
    public class Calculator {
    
        public static void main(String[] args) {
    
            //表达式
            //String expression = "50+2*6-2";
            String expression = "5-2*3+1";
    
            //创建数字栈
            ArrayStack numeStack = new ArrayStack(10);
            //创建运算符栈
            ArrayStack operatorStack = new ArrayStack(10);
    
            //初始化索引,用于扫描表达式
            int index = 0;
            int num01 = 0;
            int num02 = 0;
            int operator = ' '; //定义运算符
            int res =0;      //存放结果
            char ch =' ';  //将每次扫描得到的char保存到ch
            // 定义字符串,拼接多位数
            String str="";
    
            while (true){
                //开始扫描表达式,并判断是数字还是符号
                ch=expression.substring(index,index+1).charAt(0);
                //如果为运算符
                if (operatorStack.isOperator(ch)){
                    //判断符号栈是否为空  符号栈不为空
                    if (!operatorStack.isEmpty()){
                        //判断符号优先级  当前符号优先级小于或者等于符号栈顶的符号的优先级,
                        //从数字栈弹出两个数字,符号栈弹出栈顶符号,进行计算,结果加入数字栈,当前符号加入符号栈
                        if (operatorStack.priority(ch) <= operatorStack.priority(operatorStack.peek())){
                            num01=numeStack.pop();
                            num02=numeStack.pop();
                            operator=operatorStack.pop();
                            //进行计算
                            res=numeStack.calculator(num01,num02,operator);
                            operatorStack.push(ch);
                            numeStack.push(res);
                        }else { //当前符号的优先级大于符号栈顶的符号的优先级,则直接加入符号栈
                            operatorStack.push(ch);
                        }
                    }else { //符号栈为空
                        operatorStack.push(ch);
                    }
                }else {
                    //不是运算符  直接进入树栈
                    //ASCII表, 查出来的是'1' 对应的十进制为49
                    //numeStack.push(ch-48);
                    //某一字符为多位数时,需要当成字符串处理
                    str+=ch;
                    //判断ch是否为最后一个字符
                    if (index == expression.length()-1){
                        numeStack.push(Integer.parseInt(str));
                    }else {
                        //判断下一位是否是字符,下一位是字符,则将当前拼接字符串存入数字栈
                        if (operatorStack.isOperator(expression.substring(index+1,index+2).charAt(0))){
                            numeStack.push(Integer.parseInt(str));
                            //把str 清空
                            str = "";
                        }
                    }
                }
                //继续扫描,索引增加,并判断是否到最后
                index++;
                if (index >= expression.length()){
                    break;
                }
            }
    
            //表达式扫描完毕后,对两个栈中元素进行计算
            while (true){
                num01=numeStack.pop();
                num02=numeStack.pop();
                operator=operatorStack.pop();
                numeStack.push(numeStack.calculator(num01, num02, operator));
                //判断结束
                if (operatorStack.isEmpty()){
                    break;
                }
            }
            //输出结果
            System.out.println("result="+numeStack.pop());
    
        }
    
    }
  • 相关阅读:
    input宽度自适应
    七牛云上传 图片
    删除文件夹所有内容
    无法获取 div123 的内部内容,因为该内容不是文本。
    关于"无法删除数据库 'xxx',因为该数据库当前正在使用" 解决办法
    Asp.Net 获取FileUpload控件的文件路径、文件名、扩展名
    asp.net复制整个文件夹
    多行文本框内容转换空格换行
    花(唯一分解定理+排列组合+快速幂)
    Xn数列(矩阵乘法+快速幂+慢速乘法)
  • 原文地址:https://www.cnblogs.com/jiushixihuandaqingtian/p/11241049.html
Copyright © 2020-2023  润新知