leetcode/
basic_calculator_ii.rs

1//! # Basic Calculator II
2//!
3//! 给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
4//!
5//! 整数除法仅保留整数部分。
6//!
7//! 你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。
8//!
9//! 注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。
10//!
11//!
12//!
13//! 示例 1:
14//!
15//! 输入:s = "3+2*2"
16//! 输出:7
17//! 示例 2:
18//!
19//! 输入:s = " 3/2 "
20//! 输出:1
21//! 示例 3:
22//!
23//! 输入:s = " 3+5 / 2 "
24//! 输出:5
25//!
26//!
27//! 提示:
28//!
29//! 1 <= s.length <= 3 * 105
30//! s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
31//! s 表示一个 有效表达式
32//! 表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1] 内
33//! 题目数据保证答案是一个 32-bit 整数
34
35pub struct Solution;
36
37enum Op {
38    Add,
39    Sub,
40    Mul,
41    Div,
42}
43
44impl Op {
45    fn eval(&self, a: i32, b: i32) -> i32 {
46        match self {
47            Op::Add => a + b,
48            Op::Sub => a - b,
49            Op::Mul => a * b,
50            Op::Div => a / b,
51        }
52    }
53}
54
55impl Solution {
56    pub fn calculate(s: String) -> i32 {
57        s.bytes()
58            .chain(std::iter::once(b'+'))
59            .fold((0, 0, 0, Op::Add), |(res, prev, cur, op), c| match c {
60                b'0'..=b'9' => (res, prev, cur * 10 + (c - b'0') as i32, op),
61                b'+' => (res + op.eval(prev, cur), 0, 0, Op::Add),
62                b'-' => (res + op.eval(prev, cur), 0, 0, Op::Sub),
63                b'*' => (res, op.eval(prev, cur), 0, Op::Mul),
64                b'/' => (res, op.eval(prev, cur), 0, Op::Div),
65                _ => (res, prev, cur, op),
66            })
67            .0
68    }
69}
70
71#[cfg(test)]
72mod tests {
73    use super::Solution;
74
75    #[test]
76    fn test() {
77        assert_eq!(Solution::calculate("3+2 *2".to_string()), 7);
78        assert_eq!(Solution::calculate("3/2 ".to_string()), 1);
79        assert_eq!(Solution::calculate("3+5/2".to_string()), 5);
80    }
81}