77Lifeworkベータ版

77Lifeworkベータ版

IT関係の話(ツール開発・インフラ構築)をメインとして、その他私の趣味や雑記用のブログです。ここに書いた内容が少しでも参考になれば嬉しいです。

基本情報技術者試験(令和元年・秋季)のアルゴリズム解説③

はじめに

こんにちは。この記事は下の記事の続きの内容となっています。
www.77-lifework.com


ではやっていきましょう。

設問3(gとh)の考え方

ここでは関数GenerateBitMaskを拡張し、検索対象文字列のPat[]に正規表現が含まれている場合にも対応できるような関数GenerateBitMaskRegexについて考えていきます。

この設問で扱う正規表現については問題文の表4にある通りです。
f:id:J-back:20210802122340p:plain:w600

この正規表現を関数GenerateBitMaskで扱った場合、Pat[i]に[]という文字が出てきた際の処理が実装されていないため、正規表現を含む文字列を想定した通りに認識してくれません。
よって、関数GenerateBitMaskRegexではPat[i]が[や]の場合の処理を追加し、正規表現に対応するようにプログラムを変更しています。

では設問について考えていきましょう。
問われている内容は、指定されたPat[]で関数GenerateBitMaskRegexを実行したときのMask[]の値と戻り値です。
問題文に記載されている通りに処理を追っていけば回答できる内容です。

ここでは検索対象文字列をPat[]="AC[BA]A[ABC]A"としています。
この状態で関数GenerateBitMaskRegexを実行すると、1行目~3行目で
・OriginalPatLen=Pat[]の文字数=13
・PatLen=0
・Mode=0
となります。

その下のi=1から26までの繰り返し処理は設問1で回答した通りMask[i]="0"Bが入ります。
下の画像の部分です。
f:id:J-back:20210807172656p:plain:w600


さて、ここからがメインの処理です。以下の部分について考えていきます。
f:id:J-back:20210807172202p:plain:w600


OriginalPatLenは13なので、iを1から13まで1ずつ増加させる繰り返し処理となっています。
まずはi=1の場合を考えます。

【i=1の場合】
Pat[1]="A"なので、以下の①の条件は成立せず、次の処理に移ります。
f:id:J-back:20210807173351p:plain:w600


②の条件についても同じく成立せず、次の処理に移ります。
f:id:J-back:20210807173445p:plain:w600


Mode=0であるため、③の条件は成立し、PatLen=0+1=1となります。
f:id:J-back:20210807173548p:plain:w600

そして、以下の処理で
Mask[Index(Pat[1])]
=Mask[Index("A")]
=Mask[1]
に対して、
"1B"を(1-1)ビットだけ論理左シフトした値とMask[1]のビットごとの論理和
="1B"
が格納されます。
f:id:J-back:20210807174045p:plain:w600

ここまででi=1の処理は終わったので、次にi=2の処理に移ります。

【i=2】の場合
Pat[2]="C"なので、以下の①は成立しません。
f:id:J-back:20210807173351p:plain:w600

②の条件についても同じく成立しません。
f:id:J-back:20210807173445p:plain:w600

Mode=0であるため、③の条件は成立し、PatLen=1+1=2となります。
f:id:J-back:20210807173548p:plain:w600

そして、以下の処理で
Mask[3]に
"1B"を(2-1)ビットだけ論理左シフトした値とMask[3]のビットごとの論理和
="10B"
が格納されます。
f:id:J-back:20210807174045p:plain:w600


【i=3の場合】
Pat[3]="[" なので、①の条件が成立し、
Mode=1
PatLen=2+1=3
となり、i=4の処理に移ります。
f:id:J-back:20210807173351p:plain:w600


【i=4の場合】
Pat[4]="B"なので①、②の条件は成立しません。
また、Mode=1となっているので、③も成立せず、
Mask[2]に
"1B"を(3-1)ビットだけ論理左シフトした値とMask[2]のビットごとの論理和
="100B"
が格納されます。

【i=5の場合】
Pat[5]="A"なので①、②の条件は成立しません。
Mode=1なので③も成立せず、
Mask[1]に
"1B"を(3-1)ビットだけ論理左シフトした値とMask[1]のビットごとの論理和
="101B"
が格納されます。

【i=6の場合】
Pat[6]="]"なので、条件①は成立しません。
②は成立し、Modeに0が格納されてi=7の処理に移ります。
f:id:J-back:20210807173445p:plain:w600


上記のようにi=13まで処理を繰り返すと、MaskとPatLenの値は以下のようになります。
文字A:Mask[1]="111101B"
文字B:Mask[2]="010100B"
文字C:Mask[3]="010010B"

PatLen=6


正規表現の記述である"["と"]"、これらの記号に囲まれた文字すべてを含んだ文字数がOriginalPatLen=13であるのに対し、
正規表現が適用された結果の文字列(今回の場合、Pat[]="ACBAAA"や"ACAACA"などが考えられる)の文字数がPatLenとなっています。

よって設問gと設問hの答えは以下の通りです。
設問g:カ
設問h:イ

設問3(i)の考え方

次にPat[]="AC[B[AB]AC]A"の場合のMask[1]の値について考えていきます。
問題文には[]を入れ子にすることはできない、と記載があるので、想定した通りには動作しないことが示唆されますが、
これもプログラムはGenerateBitMaskRegexで処理内容に変更はないので、上記のgとhを回答したときと同様に具体的に値を入れて動きを見れば問題ありません。

・OriginalPatLen=12
・PatLen=0
・Mode=0
・Mask[i]="0"B
が最初に格納され、i=1から12までiを1ずつ増加させて以下の繰り返し処理が実行されます。
f:id:J-back:20210807172202p:plain:w600


詳細は省きますが、i=13まで処理を繰り返すと、MaskとPatLenの値は以下のようになります。

Mask[1]="1011001B"
Mask[2]="0001100B"
Mask[3]="0100010B"

PatLen=7

結局Pat[]="ACB[AB]ACA"とした場合と同様の動作をしており、もともと想定していたPat[]としては認識されていないことがわかります。

設問iの解答は以下の通りです。
設問i:ウ


以上でこの記事は終わりです。繰り返し処理を追っていくのが少し時間かかりますが、処理自体は単純なので困難な問題ではないと思います。
参考にしていただけると嬉しいです。


出典:令和元年度 秋期 基本情報技術者試験 午後 問8