配列の並びを逆にする|擬似言語のトレース解説と練習問題
関数 reverse は、配列 data の要素の並びを逆順にして返す。配列の要素番号は 1 から始まる。
プログラム
| 1 | ○整数型の配列: reverse(整数型の配列: data) |
| 2 | 整数型: n ← dataの要素数 |
| 3 | 整数型: i, tmp |
| 4 | for (i を 1 から n ÷ 2 の商 まで 1 ずつ増やす) |
| 5 | tmp ← data[i] |
| 6 | data[i] ← data[n - i + 1] |
| 7 | data[n - i + 1] ← tmp |
| 8 | endfor |
| 9 | return data |
何をしているか
先頭側と末尾側の要素を、外側から順に入れ替えて、配列を逆順にします。入替えは要素数の半分の回数で止めます。
トレースのコツ
- 入替えの相手は
n − i + 1番目です。i が 1 なら n 番目、i が 2 なら n − 1 番目です。最初に具体的な数で確かめておきます。 - 交換は3行で1組です。
tmpに逃がす → 上書きする →tmpを戻す、の順を崩さずに追います。 - 「n ÷ 2 の商」は、割り算の答えの整数部分です。n が 5 なら 2 回です。真ん中の要素は動きません。
よくある間違い
- 繰返しを n 回と数える。最後まで続けると、入れ替えたものを元に戻してしまいます。
- 交換の途中の状態(同じ値が2つある状態)を答えにする。設問が「どの行を実行した直後か」を必ず確かめます。
- 要素数が奇数のとき、真ん中の要素も入れ替わると考える。
例題:reverse({6, 1, 5, 9, 2, 3, 7}) を最後まで追う
上のプログラムを reverse({6, 1, 5, 9, 2, 3, 7}) で呼び出したときの、全ステップのトレース表です。太字は、その文で値が変わった変数です。
| # | 行 | したこと | data | n | i | tmp |
|---|---|---|---|---|---|---|
| 1 | 2 | 宣言 | {6, 1, 5, 9, 2, 3, 7} | 7 | — | — |
| 2 | 3 | 宣言 | {6, 1, 5, 9, 2, 3, 7} | 7 | 未設定 | 未設定 |
| 3 | 4 | 繰返しの初期化 | {6, 1, 5, 9, 2, 3, 7} | 7 | 1 | 未設定 |
| 4 | 4 | 条件判定(真) | {6, 1, 5, 9, 2, 3, 7} | 7 | 1 | 未設定 |
| 5 | 5 | 代入 | {6, 1, 5, 9, 2, 3, 7} | 7 | 1 | 6 |
| 6 | 6 | 代入 | {7, 1, 5, 9, 2, 3, 7} | 7 | 1 | 6 |
| 7 | 7 | 代入 | {7, 1, 5, 9, 2, 3, 6} | 7 | 1 | 6 |
| 8 | 4 | 繰返しの更新 | {7, 1, 5, 9, 2, 3, 6} | 7 | 2 | 6 |
| 9 | 4 | 条件判定(真) | {7, 1, 5, 9, 2, 3, 6} | 7 | 2 | 6 |
| 10 | 5 | 代入 | {7, 1, 5, 9, 2, 3, 6} | 7 | 2 | 1 |
| 11 | 6 | 代入 | {7, 3, 5, 9, 2, 3, 6} | 7 | 2 | 1 |
| 12 | 7 | 代入 | {7, 3, 5, 9, 2, 1, 6} | 7 | 2 | 1 |
| 13 | 4 | 繰返しの更新 | {7, 3, 5, 9, 2, 1, 6} | 7 | 3 | 1 |
| 14 | 4 | 条件判定(真) | {7, 3, 5, 9, 2, 1, 6} | 7 | 3 | 1 |
| 15 | 5 | 代入 | {7, 3, 5, 9, 2, 1, 6} | 7 | 3 | 5 |
| 16 | 6 | 代入 | {7, 3, 2, 9, 2, 1, 6} | 7 | 3 | 5 |
| 17 | 7 | 代入 | {7, 3, 2, 9, 5, 1, 6} | 7 | 3 | 5 |
| 18 | 4 | 繰返しの更新 | {7, 3, 2, 9, 5, 1, 6} | 7 | 4 | 5 |
| 19 | 4 | 条件判定(偽) | {7, 3, 2, 9, 5, 1, 6} | 7 | 4 | 5 |
| 20 | 9 | 戻る({7, 3, 2, 9, 5, 1, 6}) | {7, 3, 2, 9, 5, 1, 6} | 7 | 4 | 5 |
この例題で問われること
問 reverse({6, 1, 5, 9, 2, 3, 7}) を呼び出したときの戻り値はどれか。
答え {7, 3, 2, 9, 5, 1, 6}
- 戻り値になる data は、{6, 1, 5, 9, 2, 3, 7} → {7, 1, 5, 9, 2, 3, 7} → {7, 1, 5, 9, 2, 3, 6} → {7, 3, 5, 9, 2, 3, 6} → {7, 3, 5, 9, 2, 1, 6} → {7, 3, 2, 9, 2, 1, 6} → {7, 3, 2, 9, 5, 1, 6} と変わります。
- 9行目で返す時点の値 {7, 3, 2, 9, 5, 1, 6} が答えです。
問 7行目を1回目に実行した直後の、変数 data の値はどれか。
答え {7, 1, 5, 9, 2, 3, 6}
- 7行目は全部で3回実行されます。
- 実行した直後の data は、順に {7, 1, 5, 9, 2, 3, 6} → {7, 3, 5, 9, 2, 1, 6} → {7, 3, 2, 9, 5, 1, 6} です。
- 1回目の直後なので、答えは {7, 1, 5, 9, 2, 3, 6} です。
問 7行目が実行される回数はどれか。
答え 3
- 7行目は3回実行されます。トレース表で 7行目の行を数えると確かめられます。
練習問題 標準(10問)
本試験と同じくらいの量。レベル:基礎
- 問題01 reverse({6, 3, 2, 9, 4, 5, 1})
- 問題02 reverse({3, 9, 2, 7})
- 問題03 reverse({5, 4, 9, 2, 7, 8, 1, 6, 3})
- 問題04 reverse({3, 2, 8, 7, 6, 9, 4})
- 問題05 reverse({4, 9, 3, 6, 5, 2, 1})
- 問題06 reverse({3, 7, 6, 1, 4, 2})
- 問題07 reverse({3, 9, 7, 8, 5, 2})
- 問題08 reverse({8, 2, 5, 9, 6, 1, 4})
- 問題09 reverse({7, 1, 9, 2, 3, 4, 5})
- 問題10 reverse({2, 8, 6, 5, 3})
もっと解く(追加の20問)
- 問題11 reverse({9, 1, 8, 5, 6, 4, 7, 3})
- 問題12 reverse({1, 8, 4, 9, 3, 7, 5, 2, 6})
- 問題13 reverse({6, 7, 9, 1, 4, 2, 3})
- 問題14 reverse({4, 7, 2, 3, 5})
- 問題15 reverse({4, 7, 2, 9, 3, 8, 6, 5, 1})
- 問題16 reverse({7, 2, 9, 5})
- 問題17 reverse({4, 3, 1, 2, 7, 9, 6, 5, 8})
- 問題18 reverse({8, 7, 2, 1, 3, 5, 6, 4, 9})
- 問題19 reverse({8, 6, 5, 2, 1, 4, 7})
- 問題20 reverse({1, 7, 4, 5, 9, 8})
- 問題21 reverse({9, 1, 8, 4, 5, 3, 7})
- 問題22 reverse({1, 9, 4, 8, 2, 5})
- 問題23 reverse({9, 3, 7, 4, 6, 2})
- 問題24 reverse({2, 6, 8, 3, 5, 7})
- 問題25 reverse({6, 7, 9, 5, 1, 3})
- 問題26 reverse({4, 2, 5, 8, 7, 3, 9, 6})
- 問題27 reverse({8, 2, 9, 4, 7, 5, 3, 1, 6})
- 問題28 reverse({1, 4, 7, 9, 3, 2, 8})
- 問題29 reverse({8, 3, 6, 1, 4, 9, 7, 5, 2})
- 問題30 reverse({8, 1, 5, 9, 7})