Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >227. 基本计算器 II

227. 基本计算器 II

作者头像
张伦聪zhangluncong
发布于 2022-10-26 10:18:55
发布于 2022-10-26 10:18:55
31400
代码可运行
举报
运行总次数:0
代码可运行

实现一个基本的计算器来计算一个简单的字符串表达式的值。

字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。

示例 1:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
输入: "3+2*2"
输出: 7

示例 2:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
输入: " 3/2 "
输出: 1

示例 3:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
输入: " 3+5 / 2 "
输出: 5

说明:

  • 你可以假设所给定的表达式都是有效的。
  • 请不要使用内置的库函数 eval。

解:很经典,带括弧的整数加减乘除计算器实现,纯手打。计算器算法分两步:

  • 中缀表达式转后缀表达式(逆波兰表达式) 1.设立一个只保存运算符和(的符号栈signStack,与优先级map,如下代码 2.遍历中缀表达式,遇到数字直接输出;遇到(直接入栈;遇到+-*/先判断栈顶是否有优先级大于等于它的元素,有就把这些栈顶元素出栈输出后它入栈,没有就直接入栈;遇到)把栈顶元素出栈输出,直到碰见((出栈不输出;注意:输出的意思指的是保存到后缀表达式列表hzList中。
  • 后缀表达式计算 1.设立一个只保存数字的数字栈digitStack,如下代码 2.遍历后缀表达式,遇到数字直接入栈;遇到+-*/出栈两个元素进行对应符号计算;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
    public int calculate(String s) {
        //整数计算器
        //去掉所有空格
        s = s.replaceAll(" ", "");
        //中缀转后缀表达式,假定s只有数字()+-*/不含其它字符===========start
        List<String> hzList = new ArrayList<>();
        //运算符优先级,值大的优先计算
        Map<Character, Integer> map = new HashMap<>();
        map.put('+', 1);
        map.put('-', 1);
        map.put('*', 2);
        map.put('/', 2);
        //保存运算符栈
        Stack<Character> signStack = new Stack<>();

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            //是否为数字
            boolean isDigit = Character.isDigit(c);
            if (isDigit) {//如果为数字直接输出
                int tmp = i;
                while ((i + 1) < s.length() && Character.isDigit(s.charAt(i + 1))) {
                    i++;
                }
                hzList.add(s.substring(tmp, i + 1));
            } else if (c == '(') {//如果是左括弧直接入栈
                signStack.push(c);
            } else if (c == ')') {//如果是右括弧直接出栈输出,直到出现左括弧,(不输出
                while (signStack.peek() != '(') {
                    hzList.add(String.valueOf(signStack.pop()));
                }
                //去掉栈顶的(
                signStack.pop();
            } else {//均为+-*/运算符
                while (!signStack.isEmpty() && signStack.peek() != '(' && map.get(signStack.peek()) >= map.get(c)) {//如果栈中运算符优先级大于大于它,那么出栈输出
                    hzList.add(String.valueOf(signStack.pop()));
                }
                //最后自己入栈
                signStack.push(c);
            }
        }
        //栈中还存留符号出栈输出
        while (!signStack.isEmpty()) {
            hzList.add(String.valueOf(signStack.pop()));
        }
        //中缀转后缀表达式,假定s只有数字()+-*/不含其它字符===========end

        //计算后缀表达式成最终结果
        Stack<String> digitStack = new Stack<>();
        for (String str : hzList) {
            if (isNumeric(str)) {
                digitStack.push(str);
            } else if ("+".equals(str)) {
                int a = Integer.valueOf(digitStack.pop());
                int b = Integer.valueOf(digitStack.pop());
                digitStack.push(String.valueOf(b + a));
            } else if ("-".equals(str)) {
                int a = Integer.valueOf(digitStack.pop());
                int b = Integer.valueOf(digitStack.pop());
                digitStack.push(String.valueOf(b - a));
            } else if ("*".equals(str)) {
                int a = Integer.valueOf(digitStack.pop());
                int b = Integer.valueOf(digitStack.pop());
                digitStack.push(String.valueOf(b * a));
            } else if ("/".equals(str)) {
                int a = Integer.valueOf(digitStack.pop());
                int b = Integer.valueOf(digitStack.pop());
                digitStack.push(String.valueOf(b / a));
            }
        }
        return Integer.valueOf(digitStack.pop());
    }

    private boolean isNumeric(String str) {
        for (int i = str.length(); --i >= 0; ) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-09-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
计算器:中缀表达式转后缀表达式
例如:中缀表达式(8+9*10)-4/2+3 我们可以进行如下操作: 1、将每个操作符对应的两个操作数用括号括上(((8+(9*10))-(4/2))+3) 2、将操作符移到对应的括号外(((8(910*)+)(42)/)-3)+ 3、去掉括号即可  8910*+42/-3+
卡尔曼和玻尔兹曼谁曼
2019/01/25
2.3K0
前缀、中缀、后缀表达式「建议收藏」
关键字:概念, 前缀表达式, 前缀记法, 中缀表达式, 中缀记法, 波兰式, 后缀表达式, 后缀记法, 逆波兰式
全栈程序员站长
2022/07/05
2.1K0
【练习】计算给定算数表达式的结果
给定一个包含正整数、加(+)、减(-)、乘(*)、除(/)的算数表达式(括号除外),计算其结果。
孟君
2020/04/23
1.2K0
前缀、中缀、后缀表达式
它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前;中缀和后缀同理。 举例: (3 + 4) × 5 - 6 就是中缀表达式 - × + 3 4 5 6 前缀表达式 3 4 + 5 × 6 - 后缀表达式 中缀表达式(中缀记法) 中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。中缀表达式是人们常用的算术表示方法。 虽然人的大脑很容易理解与分析中缀表达式,但对计算
_gongluck
2018/03/08
1.3K0
golang 计算器实现
  可能有读者会疑惑我们为什么将num定义为int,我们这么做的原因是为了简便,或者说就是偷懒吧,因为如果要支持使用者输入小数,那么我们的程序在获取、处理输入方面的代码会更加复杂一点╮(╯_╰)╭。关于如何获取、处理输入,我们将在本文的最后给出答案。同时也会给出完整的计算器程序代码,或者说是给出完整的只支持整数输入的、不具备查错纠错能力的四则运算计算器
golangLeetcode
2022/08/02
8490
golang 计算器实现
数据结构之栈
后缀表达式适合计算式进行运算,但是人却不太容易写出来,尤其是表达式很长的情况下,因此在开发中,我们需要将中缀表达式转成后缀表达式。
用户11332765
2024/10/28
790
数据结构之栈
C++题解 | 逆波兰表达式相关
好久没有更新题解系列博客了,今天要学习的是 逆波兰表达式,作为计算机中的重要概念,值得花时间去学习,并且其中还必须使用 容器适配器,非常适合用来练手
北 海
2023/07/01
2110
C++题解 | 逆波兰表达式相关
四则运算表达式求值
表达式求值 对于表达式的求值,一般使用中缀表达式转后缀表达式后,对后缀表达式求值,因为对于后缀或者前缀表达式计算,计算的顺序都是唯一的. 中缀表达式转后缀表达式的方法: 1.遇到操作数:直接输出(添加到后缀表达式中) 2.栈为空时,遇到运算符,直接入栈 3.遇到左括号:将其入栈 4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。 5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈 6.最终将栈中的元素依次出栈,输出。123
DuncanZhou
2018/09/04
5590
227. 基本计算器 II
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。 整数除法仅保留整数部分。 示例 1: 输入:s = "3+2*2" 输出:7 示例 2: 输入:s = " 3/2 " 输出:1 示例 3: 输入:s = " 3+5 / 2 " 输出:5 class Solution { public int calculate(String s) { /** 有一个记录上一次出现的符号变量的 pre 加法直接入栈
编程张无忌
2021/06/01
3280
# 栈 栈的一个实际需求 栈的介绍 栈的应用场景 代码实现 栈实现综合计算器 # 栈的一个实际需求 请输入一个表达式 计算式:[722-5+1-5+3-3]点击计算【如下图】 请问:计算机底层是如何
用户9615083
2022/12/30
4320
栈
【Java数据结构和算法】009-栈:前缀、中缀、后缀表达式(逆波兰表达式)
①前缀表达式(波兰表达式):前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前;
訾博ZiBo
2025/01/06
1630
[数据结构与算法] 邂逅栈
栈的英文为(stack): 又名堆栈,它是一种运算受限的线性表。限定仅在表尾(栈顶)进行插入和删除操作的线性表
时间静止不是简史
2020/07/25
4600
前缀、中缀、后缀表达式
在函数式编程语言中,为了表示方便,出现了一些新的语法格式。所谓前缀、中缀、后缀表达式,它们之间的区别在于运算符相对与操作数的位置不同,为了说明它们的概念,首先来看一下中缀表达式。 所谓中缀表达式,就是将函数名放到两个操作数中间的表达式,其中,左侧的操作数代表函数对象或值,右侧的操作数代表函数的参数值。例如: (3 + 4) × 5 - 6 就是中缀表达式 - × + 3 4 5 6 前缀表达式 3 4 + 5 × 6 - 后缀表达式 前缀表达式 前缀表达式又称为前缀记法、波兰式,主要用于表示运算符位于操作数
xiangzhihong
2018/02/08
1.2K0
java数据结构和算法(二)
从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 和 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果
shaoshaossm
2022/12/26
3560
java数据结构和算法(二)
表达式求值问题(java)
给定一个表达式,其中运算符仅包含 +,-,*,/(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。
用户10604450
2024/03/15
1320
图解java数据结构之栈(Stack),你确定不看看吗?
1)子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。
慕容千语
2021/01/05
1.2K0
图解java数据结构之栈(Stack),你确定不看看吗?
Qz学算法-数据结构篇(表达式、递归)
从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素和次顶元素),并将结果入栈:重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果
浅辄
2023/06/09
2870
算法思想总结:栈
我们平时看到的 1+2*(3-4*5)+6/7 叫做中缀表达式,平时我们习惯用这个计算的原因是我们可以整体地去看到这个表达式并且清楚地知道各个运算符的优先级,但是计算机并不一定知道,因为他总是从前往后去遍历这个表达式。如上面这个例子,当按照计算机的逻辑去扫描了1+2的时候,并不敢直接去进行运算,因为可能后面存在一个优先级更高的操作符会优先进行计算。甚至有些时候还会出现括号这一种可以改变操作符优先级的符号!!所以这个时候,为了能够解决这个问题,就有了波兰表达式(前缀表达式)和逆波兰表达式(后缀表达式)。
小陈在拼命
2024/04/23
1000
算法思想总结:栈
有没有想过计算机是如何处理表达式的?
https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/
代码随想录
2021/07/16
6480
java-逆波兰算法
四则运算是栈的重要应用之一 中缀表达式转后缀表达式(逆波兰算法)过程 从左到右遍历中缀表达式 数字直接输出为后缀表达式一部分 如果是符号,则判断与栈顶元素的优先级 高于栈顶元素优先级直接入栈 低于或等于栈顶优先级栈顶元素出栈并输出为后缀表达式一部分(注意这里是递归比较栈顶元素的优先级并出栈),最后将当前元素入栈 直到遍历完中缀表达式,最终输出后缀表达式 下面是自己的实现源码 package com.yhq.demospringboot; import org.apache.commons.lang3.St
IT架构圈
2018/06/01
7380
相关推荐
计算器:中缀表达式转后缀表达式
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验