※前回の記事(擬似言語その③)はこちら
■
また、ITパスポートの擬似言語を初回から勉強したい方はこちら↓
■
今回は、令和5年の公開問題「問60」の解説を行います。
この問題は配列の要素の並び替えに関するもので、初見では難しく感じるかもしれませんが、解き方をマスターすれば得点源になります。
ぜひ、頑張ってマスターしましょう。
※なお、今回の内容を動画で視聴したい方は、下記をご覧ください。
目次
令和5年公開問題 問60 疑似言語の問題文
手続printArray は、配列integerArray の要素を並べ替えて出力する。手続printArrayを呼び出したときの出力はどれか。ここで、配列の要素番号は1から始まる。
[プログラム文]
001 ○print Array()
002 整数型: n,m
003 整数型の配列: integerArray ←{2, 4, 1, 3}
004 for (n を 1 から(integerArrayの要素数- 1)まで 1 ずつ増やす)
005 for (m を 1 から( integerArrayの要素数- n)まで 1 ずつ増やす)
006 if (integerArray[m] > integerArray[m + 1])
007 integerArray[m]とintegerAr ray[m + 1]の値を入れ替える
008 end if
009 end for
010 end for
011 integerArrayの全ての要素を先頭から順にコンマ区切りで出力する
ア)1,2,3,4 イ)1,3,2,4 ウ)3,1,4,2 エ)4,3,2,1
手続printArrayは、整数型配列integerArrayの要素を並べ替えて出力する機能を持っています。printArrayを呼び出した時の出力が問われており、配列の要素番号は1から始まります。
プログラム文は11行で、上記プログラム文中の行番号は便宜上、私がつけたものです。解答選択肢は「ア」「イ」「ウ」「エ」となっています。
冒頭文、プログラム文、解答選択肢を確認していきましょう。
冒頭文では、printArrayが整数型配列integerArrayの要素を並べ替えて出力すると説明されています。また、プログラム文は11行あり、宣言部、処理部、出力部に分かれています。特に、3行目では整数型配列integerArrayに2、4、1、3という要素が代入(初期化)されています。
プログラム文の解析では、1行目から3行目が宣言部、4行目から10行目が処理部、11行目が出力部となります。
この問題のキーポイントは、4行目から10行目にあるfor文とif文の理解です。ここでは、配列の要素を比較し、必要に応じて入れ替える処理が行われます。具体的には、配列の隣接する要素を比較し、大きい順(降順)になっていれば入れ替ます。
解答選択肢の中で、並べ替えプログラムとして考えると、昇順(小さい順)または降順(大きい順)の出力結果が考えられます。つまり、選択肢「ア」の1 2 3 4や「エ」の4 3 2 1などが候補になります。他の選択肢「イ」や「ウ」は、この条件に当てはまらないため、考えにくいと言えます。
以下、プログム文を1行ずつ見ていきましょう。
プログラム文 1行目~3行目「宣言部」の確認
1行目から3行目までは宣言部ということで、1行目で手続printArrayを宣言し、2行目では整数型の変数nとmを宣言しています。
そして3行目整数型の配列integerArrayを宣言し、そしてこの中に 2・4・1・3 という4つの要素を代入、初期化しています
プログラム文 4行目~10行目「処理部」の確認
それでは、処理部の4行目から10行目までを見ていきましょう。
まず4行目、こちらはfor文です。
このfor文は 10行目のend for と対応しています。
そして、この4行目のfor文ですが、nを1から「配列integerArrayの要素数-1」まで、一つずつ増やす。
この配列integerArray、今回は要素数が4でした。つまり、「nを1から3」まで、一つずつ増やす」ということになります。
要は この4行目のfor文は 3回繰り返すということですね。
続きまして5行目、またfor文が出てきました。
このfor文の入れ子構造ですが、この5行目のfor文は9行目のend for と対応しています。
そしてこのfor文は mを「1からintegerArrayの要素数 – n」まで1つずつ増やす。つまり、「1から このintegerArrayの要素数4 – n」まで1つずつ増やします。
そしてnは この4行目のforの中で 1から3まで可変でしたね。
すなわち for文が2つあるので、便宜上4行目を「for①」、5行目を「 for②」と呼びますが、まず、for① この4行目では、nを1から3まで一つずつ増やします。
そして、5行目のfor②ではどうなるかと言いますと、
- n = 1のときは、mを1から3まで増やす(4 – 1=で 3まで増やす)
- n = 2 の時は mを1から2まで増やす(4 – 2=2まで増やす)
- n=3のときは 1から 4 – 3 まで、つまり1から1までということで、増やさずに一回しか実施しない
こういった意味になります 続きまして、6行目から8行目、
こちらはIF文です。この6行目のIF文の括弧の中身の条件が正しければ7行目を実行します
この条件が正しくなければ、何も実施せずに if文を抜けます
この条件ですが、integerArray[m] > integerArray[m+1] ということで、並び合う2つの要素を比べて、例えば、mが1の場合は要素1と要素2(m+1)の中身を並べて、要素1の中身の方が大きければ、それぞれの中身の値を入れ替えます。
mが2の場合は 2番目の要素と3番目の要素の中身を比較して、2番目の要素の方の中身が大きければ2番目の要素と 3番目の要素の 中身を入れ替えます。
こういったことを繰り返す訳ですね。
トレース図を書く
それでは、ここまででプログラムの処理が分かりましたので、後はこのnが1の場合、mは1、2、3と繰り返すんでした。nが2の場合はmは1、2と繰り返し、nが3の場合は一回しか実行しない、ということでした。
以上のような動きを逐一チェックするのに役立つのが下図の「トレース図」です。
では、この配列の要素をif文を実行してみて、if文の実行が条件が正しければ実行するので、実行後であれば、入替後の要素がどうなるかというのを全部しらみつぶしに見ていきましょう。
トレース図に逐一記録していきますが、最終的に完成したトレース図を後述いたします。
順番に処理を見ていく
まず、n =1、m=1 の時、配列のintegerArrayの要素は、2、4、1、3 のため、6行目のif文では、integerArray[1] > integerArray[2] こちらは2 > 4となり条件を満たしません。よって7行目の入れ替えは実施されない。その結果、配列の要素は変わりません。
続きまして、n =1、m=2の時、配列の要素は、2、4、1、3 のままでした。こちらは、integerArray[2]、2番目の要素と3番目の要素を比較すると、今度は4と1なので条件を満たします。よって7行目の入れ替えが実施されます。そのため、2番目と3番目の要素を入れ替えるので、2、4、1、3が2、1、4、3に変更なります。
続きまして、n=1、m=3 のとき、今度は3番目の要素と4番目の要素を比較します。そうすると、4と3、4大なり3となり、条件を満たします。よって7行目の入れ替えは実施されます。この4と3が入れ替わりますので、2、1、3、4になります。
続きまして、nが2に変わりました、mは1に戻ります。この場合は、integerArray、1番目と2番目、この比較になります。2と1を比較すると、条件を満たします。よって、2と1が並べ替えされるので、2、1、3、4が1、2、3、4となります。
続きましてn=2、m=2 のとき、こちらで2番目の要素と3番目の要素を比較します。2 > 3となりますので、これは正しくありません。条件を満たさないので、入れ替えは実施されません。即ち、1、2、3、4は1、2、3、4のままです。
そして最後です。n=3、m=1の時、この時は1番目の要素と2番目の要素を比較します。そうすると、1 > 2となりますので、これは正しくありません。条件を満たしません。よって入れ替えは実施されません。要素の順番は1、2、3、4から変わらず、1、2、3、4のままなので、これが最終結果となります。よって並び替えの出力結果は、アが正解という風になります。
完成したトレース図
今回の処理をトレース図に全部埋めていくと、上図のようになります。n=1、m=1の時は、もともとは2、4、1、3という配列の順番だったんですが、if文の実行で条件が満たされなかったので、実行なし。要は配列の順番も2、4、1、3から変わりませんでした。
そういったふうにチェックを全部やっていき、最終的に1、2、3、4という風に並び替えが実行できたというわけです。
バブルソートについて(まとめ)
今回のように並び合う要素を比較し、条件に応じて入れ替えていく、こういう整列の方法をバブルソートといいます。初めて見た方はなかなか難しいアルゴリズムだなという風に苦手意識を持ったかもしれません。
しかし、何回か過去問を解いて、バブルソートというアルゴリズムはこういったものなんだとイメージできるようになると、苦もなく解けるようになります。ぜひ何回か復習して、しっかりイメージを持って、あなたの得意分野にしてください。
※次回は、令和5年問64 整数の総和を戻り値とする関数の擬似言語問題を解いていきます。