首页 > 编程语言 >后缀表达式 (又称 逆波兰表达式) Java代码的简单实现

后缀表达式 (又称 逆波兰表达式) Java代码的简单实现

时间:2022-10-17 17:35:24浏览次数:45  
标签:Java numQ offerFirst 后缀 pollFirst charQ 表达式 入栈

表达式求值问题

好久没有发随笔了,最近学习复习数据结构的时候看到了后缀表达式(逆波兰表达式)
发现了栈的精巧,自己想实现一下,本来想用C写的,但是实在太困难了,所有写了个简单的Java版本,还可以的
输入中缀表达式 可以得到计算结果

  • 中缀表达式
  • 后缀表达式 (又称 逆波兰表达式)
  • 前缀表达式(又称 波兰表达式)
中缀表达式 后缀表达式 前缀表达式
a+b ab+ +ab
a+b-c ab+c- -+abc
a+b-c*d ab+cd*- -+ab*cd

利用栈实现输入中缀字符串完成后缀计算

Java代码

由于c代码不好字符串转小数,也不好记录连续的数字,所有采用java实现;这里只涉及+ - * /(加减乘除)

package com.mhy.calculate;

import java.util.ArrayDeque;
import java.util.Deque;

public class Calculate {
    public static void main(String[] args) {
        Calculate calculate = new Calculate();
        String str = "11.2*88.9-(5*8+83.5-99)+55-88/44-(8+2-3+(55*8))-11.18-46+1";
        System.out.println(calculate.calculate(str));
        //521
    }

    public double calculate(String str){
        int nums = 0;//记录数字个数
        int length = str.length();//字符串的长度
        Deque<Double> numQ = new ArrayDeque<>();//数字栈
        Deque<Character> charQ = new ArrayDeque<>();//符号栈

        for (int i = 0; i < length; i++) {
            char x = str.charAt(i);
            if(isNum(x)){//如果x是数或者小数点
                nums++;
            }else {
                if(nums != 0){//数字入栈
                    double v = Double.parseDouble(str.substring(i - nums, i));//截取小数
                    numQ.offerFirst(v);//数字入栈
                }
                nums = 0;//重置记录个数

                if(x == '('){//判断是否为'(',
                    charQ.offerFirst(x);
                    continue;
                }else if(charQ.isEmpty()){//判断是否为空
                    charQ.offerLast(x);
                    continue;
                }

                while(true){//符号栈的弹出操作
                    if(charQ.isEmpty()) {//如果为空了
                        if(x != ')'){//并且这个字符不是')'就入栈
                            charQ.offerFirst(x);
                        }
                        break;//结束循环
                    }
                    char y = charQ.peekFirst();//获取符号的栈顶元素
                    if(y == '(' && x == ')') {//如果栈顶为'(' 且 需要入栈的是')'
                        charQ.pollFirst();//就直接'('弹出栈,')'不入栈
                        break;//结束循环
                    }
                    if(y == '(' && x != ')'){//如果栈顶为'(' 且 需要入栈的不是')'
                        charQ.offerFirst(x);//直接入栈
                        break;//结束循环
                    }
                    if(x == ')'){//如何入栈的是')' 开始弹栈进行运算
                        char p = charQ.pollFirst();//栈顶符号
                        double b = numQ.pollFirst();//后操作数
                        double a = numQ.pollFirst();//前操作数
                        numQ.offerFirst(cal(a,b,p));//结果入栈
                        continue;
                    }

                    if(operatorsRules(x,y)){//如果不是')',就符号比较,大于等于就运算
                        charQ.pollFirst();
                        double b = numQ.pollFirst();
                        double a = numQ.pollFirst();
                        numQ.offerFirst(cal(a,b,y));
                    }else {//否则符号入栈
                        charQ.offerFirst(x);
                        break;
                    }
                }
            }
        }

        if(nums != 0){//数字入栈 由于中缀输入都是以数字结尾,所以最后还需要进行运算
            double v = Double.parseDouble(str.substring(length - nums, length));
            numQ.offerFirst(v);
        }

        while(!charQ.isEmpty()){//把符号栈谈完
            char p = charQ.pollFirst();
            double b = numQ.pollFirst();
            double a = numQ.pollFirst();
            numQ.offerFirst(cal(a,b,p));
        }

        return numQ.pollFirst();//最好数字栈的栈顶就是结果
    }

    //是否为数
    public boolean isNum(char x){
        if(x == '.') return true;
        return x >= 48 && x <= 57;
    }

    //计算
    public Double cal(double a,double b,char x){
        if(x == '*') return a*b;
        if(x == '/') return a/b;
        if(x == '-') return a-b;
        if(x == '+') return  a+b;
        return null;
    }

    //符号优先级判断
    public boolean operatorsRules(char x,char y){
        if(x == '*' || x== '/'){
            if(y == '*') return true;
            else if(y == '/') return true;
            else if(y == '+') return false;
            else if(y == '-') return false;
        }
        if(x == '+' || x == '-'){
            if(y == '-') return true;
            else if(y == '+') return true;
            else if(y == '*') return true;
            else if(y == '/') return true;
        }
        System.out.println("符号输入错误");
        return false;
    }
}

标签:Java,numQ,offerFirst,后缀,pollFirst,charQ,表达式,入栈
From: https://www.cnblogs.com/shuisanya/p/16799959.html

相关文章

  • JavaWeb(一):MySql基础
    目录​​1、数据库相关概念​​​​1.1数据库​​​​1.2数据库管理系统​​​​1.3常见的数据库管理系统​​​​1.4SQL​​​​2、MySQL​​​​2.1MySQL安装​​​......
  • 一篇文章让你搞懂Java中的静态代理和动态代理
    什么是代理模式代理模式是常用的java设计模式,在Java中我们通常会通过new一个对象再调用其对应的方法来访问我们需要的服务。代理模式则是通过创建代理类(proxy)的方式间......
  • 异常处理语法结构、yield生成器及其表达式
    今日内容回顾目录今日内容回顾异常处理语法结构异常处理实战应用生成器对象自定义range功能yield冷门用法yield与return对比生成器表达式笔试题异常处理语法结构异常处......
  • Java实现Excel和Office Open XML之间的相互转换
    前言OfficeOpenXML(也被称为OOXML)是一种压缩的、基于XML的Excel、Word和演示文档格式。有时,你可能需要将Excel文件转换为OfficeOpenXML,以使其在各种应用程序和平台上可......
  • Java使用RestTemplate发送Post请求时携带参数
    Stringurl="https://www.baidu.com";HttpHeadersheaders=newHttpHeaders();//设置请求头,自己从浏览器复制一个,如果请求的网站没要求也可以不设置headers.set("us......
  • 进入python的世界_day16_python基础——异常捕获的处理、生成器对象、生成器表达式
    一、异常捕获1.错误类型语法错误>>>syntaxerror名字错误>>>namerror索引错误>>>Indexerror缩进错误>>>indentationerror等等......2.异常处理语法结构1.语法结......
  • Java 多线程(七)三大不安全案例
    一,买票//不安全买票publicclassUnsafeBuyTickets{publicstaticvoidmain(String[]args){BuyTicketsbuyTickets=newBuyTickets();new......
  • Java NIO——缓冲区Buffer
    基本介绍缓冲区(Buffer):缓冲区本质上是一个可以读写数据的内存块,可以理解成是一个容器对象(含数组),该对象提供了一组方法,可以更轻松地使用内存块,缓冲区对象内置了一些机制,能......
  • java开发工具
    Hsdis(HotSpotdisassembler)HSDIS,一个Sun官方推荐的HotSpot虚拟机JIT编译代码的反汇编插件。windows电脑上,在hsdisHotSpotDisassemblyPluginDownloads(chriswhoc......
  • python基础之异常处理、生成器对象、生成器表达式
    A-Z65-90a-z97-122迭代取值=for循环取值(每次取值都依赖于上一次取值)python基础之异常处理、生成器对象、生成器表达式目录一、异常处理语法结构1.异常的常见类型2......