學習軌道
/
Rust
Rust
/
練習
/
RPN 計算機
RPN 計算機

RPN 計算機

學習練習

簡介

堆疊是電腦科學中常用的一種集合類型。 它由兩個關鍵操作定義:push和pop。 push會把元素加到堆疊頂端。 pop會移除並回傳最頂端的元素。

把堆疊想像成一疊盤子。 你可以把盤子加到你那疊盤子的最上面,也可以拿走最上面那個盤子。 想拿到下面的盤子,就得先移開上面所有的盤子。

Rust 的向量實作std::vec::Vec可以用它的push()和pop()方法當作堆疊來用。 顧名思義,push()會把元素加到Vec的尾端,而pop()會移除並回傳最後一個元素。 這些操作可以非常快(在大 O 符號中是 O(1)),所以它們是用Vec最道地的方式之一。

堆疊很適合用來依特定順序存放任意數量的元素。 因為最後插入的元素會最先被回傳,所以堆疊通常被稱為 LIFO(後進先出,Last-In, First-Out)。 這種天生的順序可以用在很多地方,包括在計算逆波蘭表示法時追蹤狀態。

說明

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,全部免費。