当前位置: 首页 > article >正文

LeetCode 面试题 16.26. 计算器

文章目录

  • 一、题目
  • 二、C# 题解

一、题目

  给定一个包含正整数、加(+)、减(-)、乘(*)、除(/)的算数表达式(括号除外),计算其结果。

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

示例 1:

输入: “3+2*2”
输出: 7

示例 2:

输入: " 3/2 "
输出: 1

示例 3:

输入: " 3+5 / 2 "
输出: 5

说明:

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

  点击此处跳转题目。

二、C# 题解

  首先将中缀表达式转换为后缀表达式,然后计算后缀表达式:

public class Solution {
    public int Calculate(string s) {
        ArrayList   post   = new ArrayList();   // 后缀表达式
        Stack<char> opStk  = new Stack<char>(); // 操作符栈
        Stack<int>  numStk = new Stack<int>();  // 操作数栈
        int         num    = 0;                 // 存储每次扫描的数字
        
        /* 生成后缀表达式 post */
        foreach (char c in s) {
            if (char.IsNumber(c)) num = num * 10 + c - '0'; // 碰见操作数
            else if (c != ' ') {                            // 碰见操作符
                post.Add(num);
                num = 0;
                while (opStk.Count != 0 && OpPriority(opStk.Peek(), c) >= 0) // 将优先级不低于 c 的操作符弹入 post
                    post.Add(opStk.Pop());
                opStk.Push(c); // c 进栈
            }
        }
        post.Add(num);                                  // 最后一个操作数进栈
        while (opStk.Count != 0) post.Add(opStk.Pop()); // 剩余操作符进栈
        
        /* 计算后缀表达式 post */
        foreach (object o in post) {
            if (o is char c) {
                // 每次取出两个操作数
                int n2 = numStk.Pop();
                int n1 = numStk.Pop();
                
                // 计算结果,压入栈内
                int result = c switch {
                    '+' => n1 + n2,
                    '-' => n1 - n2,
                    '*' => n1 * n2,
                    '/' => n1 / n2,
                    _   => 0
                };
                numStk.Push(result);
            }
            else numStk.Push((int)o);
        }
        return numStk.Pop();
    }

    // 比较 c1 和 c2 的优先级
    // c1 > = < c2 分别返回 1 0 -1
    public int OpPriority(char c1, char c2) => c1 switch {
        '*' or '/' when c2 is '*' or '/' => 0,
        '*' or '/'                       => 1,
        '+' or '-' when c2 is '+' or '-' => 0,
        '+' or '-'                       => -1,
    };
}
  • 时间:68 ms,击败 71.43% 使用 C# 的用户
  • 内存:44.35 MB,击败 28.57% 使用 C# 的用户

  对于本题,由于只有两个优先级的操作符,因此可以简化操作:

public class Solution {
    public int Calculate(string s) {
        Stack<int> numStk = new Stack<int>();
        int        ans    = 0, num = 0;
        char       preOp  = '+'; // 上次的操作符
        for (int i = 0; i < s.Length; i++) {
            if (char.IsNumber(s[i])) num = num * 10 + s[i] - '0';
            if (!char.IsNumber(s[i]) && s[i] != ' ' || i == s.Length - 1) { // 遇见操作符或者到达结尾
                switch (preOp) { // 依据上一个操作符计算结果放入 numStk 中
                    case '+':
                        numStk.Push(num);
                        break;
                    case '-':
                        numStk.Push(-num);
                        break;
                    case '*':
                        numStk.Push(numStk.Pop() * num);
                        break;
                    case '/':
                        numStk.Push(numStk.Pop() / num);
                        break;
                }
                num = 0;
                preOp = s[i];
            }
        }
        while (numStk.Count != 0) ans += numStk.Pop(); // 结果累加
        return ans;
    }
}
  • 时间:56 ms,击败 100.00% 使用 C# 的用户
  • 内存:37.93 MB,击败 57.14% 使用 C# 的用户

http://www.kler.cn/news/134536.html

相关文章:

  • Maven引用本地jar包
  • Polygon Miden VM中的哈希函数对比
  • 2311rust,到35版本更新
  • 【论文阅读】SPARK:针对视觉跟踪的空间感知在线增量攻击
  • 基于支持向量机SVM的时间序列数据训练测试和预测未来数据,LIBSVM工具箱详解
  • OPPO Watch纯手机开启远程ADB调试
  • CMS与FullGC
  • 3D应用开发引擎HOOPS如何促进AEC数字化架构革新?
  • mybatisPlus的简单使用
  • window拖拽操作的实现
  • python连接hive报错:TypeError: can‘t concat str to bytes
  • 【面试经典150 | 数学】Pow(x, n)
  • 论文阅读:YOLOV: Making Still Image Object Detectors Great at Video Object Detection
  • Linux系统上导出和导入MongoDB数据库
  • Vue 3 和 Spring Boot 3 的操作流程和执行步骤详解
  • 视频修复软件 Aiseesoft Video Repair mac中文版功能
  • Spring Boot中使用Redis进行大数据缓存
  • 连接服务器上mysql数据库
  • 【交易误区】MT4外汇交易必读:新手常犯的交易错误有哪些?
  • 小程序开通电子发票
  • 中小企业怎么实现数字化转型?有什么实用的工单管理系统?
  • Notepad++ 和正则表达式 只保留自己想要的内容
  • idea项目中java类名出现带 j 小红点,如何解决?
  • 使用契约的链上限价订单
  • 【ArcGIS】批量对栅格图像按要素掩膜提取
  • 2024年全网最全的Jmeter+ant+jenkins实现持续集成教程
  • 磁钢的居里温度和工作温度
  • c++ list容器使用详解
  • UE基础篇十:材质
  • java多线程中的Fork和Join