IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 逆波兰表达式实现计算器----Java -> 正文阅读

[Java知识库]逆波兰表达式实现计算器----Java

逆波兰表达式就是后缀表达式,比如正常表达式(也就是中缀表达式)是"300+5*((6- 3)-2)"的一个字符串,那么它的后缀表达式形式是[300, 5, 6, 3, -, 2, -, *, +](这里我就直接用集合的形式来表达)。用中缀表达式计算算式时,我们需要考虑优先级问题,如果没有小括号,问题就很简单,可这样功能较单一。而后缀表达式不需要考虑优先级问题,关键就放在了中缀表达式转换成后缀表达式,这里有笔者写的代码可供参考。

package com.stack;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

//这里运用逆波兰表达式实现计算器功能
//支持+ - * / ()
//支持多位数。小数
//兼容处理,过滤空白字符、制表符、换页符

public class RPNCalculate {
    public static void main(String[] args) {
        String s = "  300+5*((6- 3) - 2)";//如果需要输入的话可自行添加
        List<String> infixList = ToInfixExpressionList(s);
        List<String> suffixList = parseSuffixExpressionList(infixList);
        System.out.println(suffixList);//[300, 5, 6, 3, -, 2, -, *, +]
        System.out.println(calculate(suffixList));
    }

    //将中缀表达式形式的字符串转换成中缀表达式形式的集合
    public static List<String> ToInfixExpressionList(String expression) {
        expression = expression.replaceAll("\\s+", "");//去除空白字符、制表符、换页符
        int index = 0;//索引
        char c;//存储每次取出的字符
        int len = expression.length();//字符串长度
        String str;//拼接多位数字
        List<String> list = new ArrayList<>();
        do {
            c = expression.charAt(index);
            //判断是否为数字
            if ((c + "").matches("\\d+")) {
                str = "";//初始化
                while (index < len && ((c = expression.charAt(index)) + "").matches("\\d+")) {
                    str += c;
                    index++;
                }
                list.add(str);
            } else {
                //如果不是数字则直接加入集合
                list.add("" + c);
                index++;
            }
        } while (index < len);
        return list;
    }

    //将中缀表达式集合转变成后缀表达式集合
    public static List<String> parseSuffixExpressionList(List<String> infixList) {
        Stack<String> stack = new Stack<>();//转换时放运算符
        List<String> list = new ArrayList<>();
        //遍历
        for (String s : infixList) {
            if (s.matches("\\d+"))//如果是数字直接存入集合
                list.add(s);
            else if (s.equals("("))//如果是"(",先存入栈中
                stack.push(s);
            else if (s.equals(")")) {//如果是")",则把栈中的运算符依次放入集合中,直到"("
                while (!stack.peek().equals("("))
                    list.add(stack.pop());
                stack.pop();
            } else {
                //循环判断s的优先级是否比栈顶的优先级低,成立就把栈顶的运算符拿出放到集合中
                while (stack.size() != 0 && operation(s) <= operation(stack.peek())) {
                    list.add(stack.pop());
                }
                stack.push(s);
            }
        }
        //将stack中剩余的运算符放到集合中
        while (stack.size() != 0)
            list.add(stack.pop());

        return list;
    }

    //逆波兰表达式的计算
    public static float calculate(List<String> list){
        Stack<Float> stack=new Stack<>();
        for (String s : list) {
            if (s.matches("\\d+"))
                stack.push(Float.valueOf(s));
            else {
                float num2=stack.pop();
                float num1=stack.pop();
                switch (s){
                    case "+":
                        stack.push(num1+num2);
                        break;
                    case "-":
                        stack.push(num1-num2);
                        break;
                    case "*":
                        stack.push(num1*num2);
                        break;
                    case "/":
                        stack.push(num1/num2);
                        break;
                    default:
                        break;
                }
            }
        }
        return stack.pop();
    }

    //判断运算符的优先级,返回的数越大,运算级越高
    public static int operation(String s) {
        switch (s) {
            case "+":
            case "-":
                return 1;
            case "*":
            case "/":
                return 2;
            case "(":
                return 0;
            default:
                throw new RuntimeException(s + "不是运算符,请重新输入!");
        }
    }
}

万分感谢大家的阅读,有不足的地方希望大家可以指出。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-14 21:29:54  更:2021-11-14 21:30:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:37:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码