【备战蓝桥杯】 算法·每日一题(详解+多解)-- day12

简介: 【备战蓝桥杯】 算法·每日一题(详解+多解)-- day12

【备战蓝桥杯】 算法·每日一题(详解+多解)-- day12


✨博主介绍

计算器问题的双栈通用解法

题目

解题思路

💫点击直接资料领取💫


✨博主介绍


🌊 作者主页:苏州程序大白


🌊 作者简介:🏆CSDN人工智能域优质创作者🥇,苏州市凯捷智能科技有限公司创始之一,目前合作公司富士康、歌尔等几家新能源公司


💬如果文章对你有帮助,欢迎关注、点赞、收藏


💅 有任何问题欢迎私信,看到会及时回复

💅关注苏州程序大白,分享粉丝福利


计算器问题的双栈通用解法


题目

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。


整数除法仅保留整数部分。


示例 1:

输入:s = “(1+(4+5+2)-3)+(6+8)”

输出:23


示例 2:

输入:s = “ 3+5 / 2 “

输出:5


注意:
这一类题有多种变式,如  `224 `. 基本计算器 中表达式只含有 `+`, ` - ` 和  `() `, `227 `。
基本计算器  `II ` 中含有  `+ `,  `- `, *, ` / `, `772 `. 基本计算器  `III ` 中含有 ` + `, `-, `  `* `,  `/ ` 以及  `() `。
介绍的双栈通用解法适用于以上所有题目。


解题思路


首先创建两个栈nums和 ops,分别存放表达式中的数字和操作符。


然后从前往后遍历表达式,对于遍历到的字符做分类讨论。


空格:跳过


(:加入到 ops 中,等待与之匹配的 )


):使用现有的 nums 和 ops 进行计算,直到遇到左边最近的一个左括号为止,计算结果放回到 nums。


数字 : 从当前位置开始继续往后取,将整一个连续数字整体取出,加入 nums。


运算符:加入到 ops 中。在加入之前先把栈内可以算的都算掉(只有「栈内运算符」比「当前运算符」优先级高/同等,才进行运算),使用现有的 nums 和ops进行计算,直到没有操作或者遇到左括号,计算结果放到 nums。


其中, 只有「栈内运算符」比「当前运算符」优先级高/同等,才进行运算 的意思是:假设当前已经扫描到了 2 + 1(此时栈内的操作为 + )。


如果后面出现的+ 2 或者- 1 的话,满足「栈内运算符」比「当前运算符」优先级高/同等,可以将 2 + 1 算掉,把结果放到 nums 中;

如果后面出现的是* 2或者/ 1的话,不满足「栈内运算符」比「当前运算符」优先级高/同等,这时候不能计算 2 + 。


一些细节:


由于第一个数可能是负数,为了减少边界判断。一个小技巧是先往 nums 添加一个0为防止()内出现的首个字符为运算符,将所有的空格去掉,并将 (- 替换为 (0-,(+ 替换为 (0+(当然也可以不进行这样的预处理,将这个处理逻辑放到循环里去做)。


class Solution {
  public int calculate(String s) {
    // 使用一个 Map 来维护运算符的优先级
    Map<Character, Integer> map = new HashMap<>();
    map.put('-', 1);
    map.put('+', 1);
    map.put('*', 2);
    map.put('/', 2);
    ArrayDeque<Integer> nums = new ArrayDeque<>();
    ArrayDeque<Character> ops = new ArrayDeque<>();
    // 防止第一个字符是负号,现在 nums 中添加一个 0
    nums.addLast(0);
    // 去掉所有空格
    s = s.replace(" ", "");
    char[] cs = s.toCharArray();
    for (int i = 0; i < cs.length; i++) {
      char c = cs[i];
      if (c == '(') {
        ops.addLast(c);
      } else if (c == ')') {
        // 运算 直到碰到与之对应的 (
        while (ops.peekLast() != '(') {
          calc(nums, ops);
        }
        // 运算完将 ( 弹出
        ops.pollLast();
      } else if (isNum(c)) {
        int sum = 0;
        int j = i;
        // 将数字整体取出
        while (j < cs.length && isNum(cs[j])) {
          sum = sum * 10 + (cs[j] - '0');
          j++;
        }
        nums.addLast(sum);
        // 遍历下标前移
        i = j - 1;
      } else {
        // 在特殊情况 (- 或 (+ 中加上 0
        if (i > 0 && cs[i - 1] == '(') {
          nums.addLast(0);
        }
        // 将运算符加入 ops 前先把能算的算完
        while (!ops.isEmpty() && ops.peekLast() != '(') {
          char prev = ops.peekLast();
          // 判断上一个运算符与当前的优先级关系
          if (map.get(prev) >= map.get(c)) {
            calc(nums, ops);
          } else {
            break;
          }
        }
        // 将运算符加入 ops
        ops.addLast(c);
      }
    }
    // 遍历结束 完成剩余运算
    while (!ops.isEmpty()) {
      calc(nums, ops);
    }
    return nums.peekLast();
  }
  void calc(ArrayDeque<Integer> nums, ArrayDeque<Character> ops) {
    // 数字数量小于 2 或运算符数量等于 0,不进行运算
    if (nums.size() < 2)
      return;
    if (ops.isEmpty())
      return;
    // 弹出两个数字
    int b = nums.pollLast();
    int a = nums.pollLast();
    // 弹出一个运算符
    char o = ops.pollLast();
    int c = 0;
    if (o == '-') {
      c = a - b;
    } else if (o == '+') {
      c = a + b;
    } else if (o == '*') {
      c = a * b;
    } else {
      c = a / b;
    }
    // 计算结果放回 nums
    nums.addLast(c);
  }
  boolean isNum(char c) {
    return Character.isDigit(c);
  }
}



相关文章
|
28天前
|
算法 搜索推荐 Java
【潜意识Java】深度解析黑马项目《苍穹外卖》与蓝桥杯算法的结合问题
本文探讨了如何将算法学习与实际项目相结合,以提升编程竞赛中的解题能力。通过《苍穹外卖》项目,介绍了订单配送路径规划(基于动态规划解决旅行商问题)和商品推荐系统(基于贪心算法)。这些实例不仅展示了算法在实际业务中的应用,还帮助读者更好地准备蓝桥杯等编程竞赛。结合具体代码实现和解析,文章详细说明了如何运用算法优化项目功能,提高解决问题的能力。
58 6
|
28天前
|
算法 Java C++
【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题
本文介绍了经典的0/1背包问题及其动态规划解法。
48 5
|
4月前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
4月前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
蓝桥杯Python编程练习题的集合,涵盖了从基础到提高的多个算法题目及其解答。
163 3
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
|
2天前
|
算法 数据安全/隐私保护 计算机视觉
基于FPGA的图像双线性插值算法verilog实现,包括tb测试文件和MATLAB辅助验证
本项目展示了256×256图像通过双线性插值放大至512×512的效果,无水印展示。使用Matlab 2022a和Vivado 2019.2开发,提供完整代码及详细中文注释、操作视频。核心程序实现图像缩放,并在Matlab中验证效果。双线性插值算法通过FPGA高效实现图像缩放,确保质量。
|
1月前
|
算法 数据安全/隐私保护 计算机视觉
基于Retinex算法的图像去雾matlab仿真
本项目展示了基于Retinex算法的图像去雾技术。完整程序运行效果无水印,使用Matlab2022a开发。核心代码包含详细中文注释和操作步骤视频。Retinex理论由Edwin Land提出,旨在分离图像的光照和反射分量,增强图像对比度、颜色和细节,尤其在雾天条件下表现优异,有效解决图像去雾问题。
|
1月前
|
算法 数据可视化 安全
基于DWA优化算法的机器人路径规划matlab仿真
本项目基于DWA优化算法实现机器人路径规划的MATLAB仿真,适用于动态环境下的自主导航。使用MATLAB2022A版本运行,展示路径规划和预测结果。核心代码通过散点图和轨迹图可视化路径点及预测路径。DWA算法通过定义速度空间、采样候选动作并评估其优劣(目标方向性、障碍物距离、速度一致性),实时调整机器人运动参数,确保安全避障并接近目标。
147 68
|
1月前
|
算法 数据安全/隐私保护
室内障碍物射线追踪算法matlab模拟仿真
### 简介 本项目展示了室内障碍物射线追踪算法在无线通信中的应用。通过Matlab 2022a实现,包含完整程序运行效果(无水印),支持增加发射点和室内墙壁设置。核心代码配有详细中文注释及操作视频。该算法基于几何光学原理,模拟信号在复杂室内环境中的传播路径与强度,涵盖场景建模、射线发射、传播及接收点场强计算等步骤,为无线网络规划提供重要依据。
|
3天前
|
传感器 算法 物联网
基于粒子群算法的网络最优节点部署优化matlab仿真
本项目基于粒子群优化(PSO)算法,实现WSN网络节点的最优部署,以最大化节点覆盖范围。使用MATLAB2022A进行开发与测试,展示了优化后的节点分布及其覆盖范围。核心代码通过定义目标函数和约束条件,利用PSO算法迭代搜索最佳节点位置,并绘制优化结果图。PSO算法灵感源于鸟群觅食行为,适用于连续和离散空间的优化问题,在通信网络、物联网等领域有广泛应用。该算法通过模拟粒子群体智慧,高效逼近最优解,提升网络性能。
|
3天前
|
机器学习/深度学习 数据采集 算法
基于GWO灰狼优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
本项目基于MATLAB2022a,展示了时间序列预测算法的运行效果(无水印)。核心程序包含详细中文注释和操作视频。算法采用CNN-GRU-SAM网络,结合灰狼优化(GWO),通过卷积层提取局部特征、GRU处理长期依赖、自注意力机制捕捉全局特征,最终实现复杂非线性时间序列的高效预测。