今回は単方向リストの解説についてこちらの教材、予想問題①科目B:問8で
解説していこうと思います。すでに購入された方向けとなりますので、
ご理解ください。
かんたん合格 基本情報技術者予想問題集 令和5年度
なぜこの問題を解説するのか
・twitterのフォロワーの方のツイートを見て自分も同じ内容で理解できない部分があった為、この機会にどのような処理になっているのか理解するために解説することにしました。問題のポイント
・この問題を解くためにはまず「単方向リスト」について知っておかなければなりません。※問題集の解説を見たらある程度分かると思います。
・ただしく問題を理解する
今回紐解いてみて見落としていた部分がたくさんあったのでそちらをふまえて解説します。
解説
まずは小さなところから順を追って紐解いていきます。※問題については載せられない為、手元の教材を見ながら進めてください。
処理の流れについて解説します。
①関数appendが文字列を引数に取り、発火します。
②ListElement型: prev,currが宣言される。
③currがコンストラクタ(qval)で文字列valを格納する。
④条件分岐、trueの場合currがlistHeadに格納される。
⑤条件分岐、falseの場合、prevにlistHeadが格納される。
⑤-① 繰り返し処理、prev.nextが未定義ではない場合prevにprev.nextが格納される。
⑥prev.nextにcurrが格納される。
②,③prev,currの役割について
ここで宣言されるprev,currがどのように使われるのか詳しく見てみるとcurrはコンストラクタを用いて初期化を行っており、新しい要素を格納する変数ということが見て取れます。prevについて、prevはlistHeadを格納しており、参照を取得しているよう見て取れる。その為prevはlistHeadを直接操作しない為の一時変数のような役割だと理解しました。④listHeadにcurrを格納する
条件分岐の中で行う操作を考えた時, ListHeadにcurrを格納する操作をしている。格納する場合のケースとしてどのような場面が考えられるかというと、先頭に要素が何もない場合(つまり未定義の場合)に格納しなければならないと推測ができると思います。※PGの方なら未定義の参照はExceptionが発生すると言ったら理解できるかもしれませんね。 よって問題aについては未定義である場合にtrue判定にする必要があると理解できると思います。⑤prevにlistHeadを格納する
まず前提としてlistHeadとはについてですが、大まかにグローバルな変数と理解しました。なのでlistHead自体をそのまま操作可能かと思いますが、あえてprevに格納する手順が記載してあります。※プログラミングのお作法で直接データ操作を行うのはご法度だった気が...。⑤‐① prev.nextが未定義ではない場合にprevにprev.nextが格納される
こちらは④とは逆になり、既にlistHeadには1つ以上のデータが存在する状態だということになります。なぜこの操作を行う必要があるのかというと、単方向リストの一番最後にデータを格納したい=未定義にデータを格納する為、一番最後の要素にアクセスする手順を踏んでいるいるということになります。⑥prev.nextにcurrが格納される。
ここが僕も理解できなかったポイント。当時の僕はcurr.nextを選択していたと思います。答えとしてcurrが正解になるのですが、それについて理解するにはデータ構造に着目する必要がありました。prev.nextにはどんな参照を入れなければならないのかについて考えます。上の表にはLisrElementが持つ変数等の記載あると思います。そちらのnextの型を確認するとListElement型を格納すると記載がありました。(僕の見落としポイント)型が分かればあとは答えがわかるはずです。今回、単方向リストの末尾に追加したい要素は引数qvalの値、すなわちcurrに格納されていることがわかりました。またcurrはListElement型で定義がされており、currそのものを格納する必要があると理解しました。(再起処理みたいなイメージで考えたらわかりやすいかも...)以上が解説になります。
分からないことがあれば質問してください。