轨道
/
Rust
Rust
/
练习
/
RPN 计算器
RPN 计算器

RPN 计算器

学习练习

简介

栈是计算机科学中常用的一种集合类型。 它由两个关键操作定义:push和pop。 push把一个元素添加到栈顶。 pop移除并返回最上面的元素。

可以把栈想象成一摞盘子。 你可以往这摞盘子的顶部再放一个盘子,也可以取走最上面的那个盘子。 要拿到下面更靠里的盘子,就得先拿走它上面所有的盘子。

Rust 的向量实现 std::vec::Vec可以通过它的push()和pop()方法当作栈来用。 自然,push()把一个元素添加到Vec的末尾,而pop()移除并返回最后一个元素。 这些操作可以非常快(在大 O 表示法中为 O(1)), 因此它们是最符合习惯的Vec用法之一。

栈很适合按特定顺序保存任意数量的元素。 因为最后插入的元素最先被返回, 所以栈通常被称为LIFO(后进先出)。 这种固有的顺序有很多用途, 包括在求值逆波兰表示法时跟踪状态。

说明

1. 概览

逆波兰表示法(RPN)是一种书写数学表达式的方式。 与传统的中缀表示法不同,RPN 的运算符跟在操作数后面。 例如,不写成:

2 + 2

而是写成:

2 2 +

逆波兰表示法的主要优点是,它比中缀表示法容易解析得多。 RPN 免去了复杂表达式中的运算顺序规则和括号。 例如:

(4 + 8) / (7 - 5)

可以写成

4 8 + 7 5 - /

这两种情况下,表达式的求值结果都是 6。

2. 示例

让我们手动对这个复杂表达式求值。 正如我们在介绍中学到的,RPN 的求值需要一个栈。 这个栈用来存放运算符所操作的数值。 我们让计算器从空栈开始,然后依次对每个元素求值。

首先,我们遇到一个4, 于是把它压入刚创建好的栈。

4

接下来,我们遇到一个8。 也把它压入栈。

4 8

现在,我们遇到一个+。 我们弹出最上面的两个值(4 和 8), 把它们相加, 再把和压回栈中。

12

我们对7、5和-做类似的事情:

12 7
12 7 5
12 2

现在我们遇到一个/。 尽管上一个遇到的是-, 但栈上有两个元素。 我们弹出这两个元素, 把它们相除, 再把结果压回栈中。

6

最后,由于栈上恰好有一个元素, 我们可以说该表达式的求值结果是 6。

3. 目标

你的目标是编写一个计算器,对一组按逆波兰表示法排列的输入进行求值,并返回栈上最后剩下的元素。

如果最后栈中不是恰好一个元素,则返回 None。

如果某个运算符的操作数太少(比如输入 2 +),则返回 None。

我们为你提供了下面的枚举和存根函数,作为起点。

#[derive(Debug)]
pub enum CalculatorInput {
    Add,
    Subtract,
    Multiply,
    Divide,
    Value(i32),
}

pub fn evaluate(inputs: &[CalculatorInput]) -> Option<i32> {
    todo!(
        "Given the inputs: {inputs:?}, evaluate them as though they were a Reverse Polish notation expression"
    );
}
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Rust Exercism

准备好开始 RPN 计算器 了吗?

注册 Exercism,借助 99 个练习 和真人导师指导,学习并掌握 Rust,全部免费。