ジェネリックスタック
CoddyのRustジャーニー「Object Oriented Programming」セクションの一部 — レッスン 59/61。
チャレンジ
簡単スタックは、「後入れ先出し」(LIFO: Last In, First Out)の原則に従う基本的なデータ構造です。最後に追加されたアイテムが最初に取り出されます。皿の積み重ねを想像してください。皿は一番上に追加し、一番上から取り出します。
どんな型の要素でも保持できるジェネリックな Stack データ構造を構築しましょう!スタックは「後入れ先出し」の原則に従います。これは、本を積み重ねたときのように、一番上からしか追加や取り出しができない状態と同じです。
コードは2つのファイルに分けて構成します:
stack.rs: 内部で要素を格納するためにVec<T>を使用するジェネリックなStack<T>構造体を定義します。3つのメソッドを実装してください:空のスタックを作成するnew、要素を一番上に追加するpush、そして一番上の要素を取り出して返すpop(スタックが空の場合があるため、Option<T>を返します)です。main.rs: 作成したスタックモジュールを取り込み、整数を使用してStackの動作を実演します。スタックを作成し、提供された数値をプッシュした後、要素をポップしてそれぞれを出力します。pop によって返されるOptionを処理するためにunwrap_orを使用してください。スタックが空の場合は、デフォルト値として-1を使用します。
スタックには2つの不可欠な操作が必要です:
- push — スタックの一番上に要素を追加します
- pop — 一番上の要素を取り出して返します
スタックが空である可能性があるため、pop メソッドは Option<T> を返す必要があります。Vec 型には既に Option<T> を返す pop メソッドがあり、実装に活用できます。
スタックは次のように動作する必要があります:値 10、20、30 を(この順序で)プッシュした場合、3回ポップすると 30、20、10(逆順)が得られます。空のスタックに対して4回目のポップを行うと、デフォルト値が返されるはずです。
ポップされた各値をそれぞれの行に出力してください:
30
20
10
-1例えば、入力が 5、15、25 の場合:
25
15
5
-13つの入力を受け取ります:スタックにプッシュする3つの整数(それぞれ i32 としてパースしてください)。3つすべてをプッシュした後、4回ポップして、成功したポップとスタックが空の場合の両方のケースを示してください。
自分で試してみよう
mod stack;
use stack::Stack;
fn main() {
// 入力から3つの整数を読み取る
let mut input1 = String::new();
std::io::stdin().read_line(&mut input1).expect("Failed to read line");
let num1: i32 = input1.trim().parse().expect("Invalid number");
let mut input2 = String::new();
std::io::stdin().read_line(&mut input2).expect("Failed to read line");
let num2: i32 = input2.trim().parse().expect("Invalid number");
let mut input3 = String::new();
std::io::stdin().read_line(&mut input3).expect("Failed to read line");
let num3: i32 = input3.trim().parse().expect("Invalid number");
// TODO: 新しい Stack を作成する
// TODO: 3つの数値をスタックにプッシュする (num1, num2, num3 の順に)
// TODO: 4回ポップし、各結果を表示する
// 空のスタックの場合を処理するために unwrap_or(-1) を使用する
}