クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

スタックとキューの使い方

このレッスンのあとで: スタックとキューを使って、問題を解くことができる。

50分のレッスンコマンド6件コンパイラとアーキテクチャのラボ:gcc、flex、bison、RISC-V を1台の VM で

最後に入れたものを、最初に出す

スタックとは、最後に入れたものを、最初に取り出す入れ物です。キューは反対に、最初に入れたものを、最初に取り出します。この2つが解ける問題を見分けられるようになります。

エディタの「元に戻す」は、直前の操作から順に戻ります。コピー機の印刷待ちは、出した順に印刷されます。

このレッスンのゴール

メモ

スタックとキューを使って、問題を解くことができる。

重要な言葉

ことばいみ
スタック後に入れたものから先に出る入れ物。後入れ先出し(LIFO)
キュー先に入れたものから先に出る入れ物。先入れ先出し(FIFO)
プッシュスタックの一番上に、1つ積むこと
ポップスタックの一番上から、1つ取り出すこと
エンキューとデキューキューに入れることと、取り出すこと

学生が入力するセルは、このプレビューでは空白です。

スタックは一番上だけを触る

スタックは、本を積み重ねた山と同じです。足すのも取るのも、一番上だけです。

プッシュで一番上に積み、ポップで一番上を取ります。取り出せるのは、最後に積んだものです。真ん中を直接取ることはできません。

例: 元に戻す操作の流れ

操作スタックの中(下から上)出るもの
プッシュ「料金」料金
プッシュ「は」料金、は
プッシュ「300円」料金、は、300円
ポップ料金、は300円
ポップ料金は

学生が入力するセルは、このプレビューでは空白です。

リストで作った、元に戻す機能

コード: python
# エディタの「元に戻す」を、スタックで作ります。
history = []
text = ""
for word in ["料金", "は", "300円", "です"]:
    history.append(text)      # 変える前の文を積みます。
    text = text + word
print("今の文:", text)
text = history.pop()          # 元に戻すと、最後に積んだものが出ます。
print("1回戻す:", text)
text = history.pop()
print("2回戻す:", text)
# 3回目の history.pop() を足して、実行しましょう。

キューは前から出して、後ろに足す

キューは、駅の券売機の行列と同じです。新しい人は一番後ろに並び、一番前の人から買います。

エンキューで後ろに入れ、デキューで前から出します。出る順番は、入れた順番と同じです。印刷待ちや、順番に処理する仕事に向きます。

例: 印刷待ちの流れ

操作キューの中(前から後ろ)出るもの
エンキュー「成績表」成績表
エンキュー「請求書」成績表、請求書
エンキュー「地図」成績表、請求書、地図
デキュー請求書、地図成績表
デキュー地図請求書

学生が入力するセルは、このプレビューでは空白です。

スタック: 後に入れた2が先に出る

コマンド
python3 -c "s = []; s.append(1); s.append(2); print(s.pop(), s.pop())"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

キュー: 先に入れた a が先に出る

コマンド
python3 -c "from collections import deque; q = deque(); q.append('a'); q.append('b'); print(q.popleft(), q.popleft())"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

括弧の対応は、スタックで調べる

式の括弧が正しく閉じているかは、コンパイラが最初に確かめることの1つです。開き括弧が来たらプッシュします。閉じ括弧が来たらポップして、対になる種類か調べます。

最後にスタックが空なら、正しい式です。ラボの電卓も、同じ考え方で括弧を読みます。

括弧を調べる小さなコード

コード: python
# 開き括弧を積み、閉じ括弧が来たら取り出して、対になるか調べます。
text = "(2 + [3 * 4])"
pairs = {")": "(", "]": "["}
stack = []
ok = True
for ch in text:
    if ch == "(" or ch == "[":
        stack.append(ch)
    elif ch == ")" or ch == "]":
        if len(stack) == 0 or stack.pop() != pairs[ch]:
            ok = False
print(ok and len(stack) == 0)
# text を "(2 + [3 * 4)]" に変えて、もう一度実行しましょう。

コンパイラのフォルダに入る

コマンド
cd ~/compiler

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

電卓を用意する

コマンド
make

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

括弧が合っている式

コマンド
echo "(2 + 3) * 4" | ./calc

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

閉じ括弧が足りない式

コマンド
echo "(2 + 3" | ./calc

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

よくある間違い

注意

括弧は、開きの数と閉じの数が同じなら正しい、と思いがちです。)( は数が同じでも誤りで、[(1 + 2]) も種類が交差しています。順番と種類を見るために、数えるのではなくスタックを使います。

このラボとソースについて: コンパイラとアーキテクチャのラボ:gcc、flex、bison、RISC-V を1台の VM で

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。