問13 次の Fortran プログラムの説明及びプログラムを読んで,設問に答えよ。
〔プログラムの説明〕
英字(“a”〜“z”)からなる長さ m(1 ≦ m ≦ 100)の文字列を入力して, その文字列を圧縮した結果として生成される文字列を出力するプログラムである。
(1) 文字列を配列 ca に入力し,入力した文字列の後に,空白文字“ ”を圧縮処理の ために付加する。
(2) 入力した文字列を調べ,同じ英字が連続して出現した場合,連続している英字を 3文字からなる変換記号列(制御記号,反復回数,反復文字)に置き換える。
(3) 制御記号は,入力した文字列中で,最も出現回数の少ない文字とする(ここで, 文字列中に 1 度も出現しなかった英字は出現回数を 0 とする)。プログラムでは, 組込み関数 minloc を利用して制御記号を選んでいる。minloc は,引数で指定した配列の 要素の中で最小値の要素の添字の値を 1 次元配列に返す。最小値の要素が複数個ある ときには,添字が返される要素は添字の値が最小となっている要素である。
(4) 反復回数は,1 →“a”,2 →“b”,…,26 →“z”として表わし,27 以上の 場合は 26 以内となるように変換記号列を繰り返す。
例:30 個の連続した“a”を圧縮した結果は,制御記号が“q”のとき,“qzaqda”となる。
(5) 変換記号列は 3 文字を必要とするので,連続する同じ英字の文字数が 3 以下の 場合には変換記号列に置き換えない。ただし,その英字が制御記号として選択されている ときは,復号(圧縮前のデータに戻すこと)ができなくなるのを防ぐため,変換記号列に 必ず置き換える。
例:制御記号が“v”のとき,入力文字列中の“vv”は,“vbv”となる。
(6) プログラムでは,文字列を処理するために,組込み関数 iachar と achar を 利用している。iachar(c) は,ASCII 大小順序における文字 c の番号を返す。 achar(i) は,ASCII 大小順序における順序位置 i の文字を返す。
例:achar(iachar('a')+1) = 'b'
(7) 入力データ及び出力結果の例を図 1,2 に示す。
31 aaaaaabbccccddddddeeffffggggggg 図1 入力データ例 control mark = h data size = 19 hfabbhdchfdeehdfhgg 図2 出力結果例
〔プログラム〕 (行番号) 01 character,dimension(101) :: ca 02 character,dimension(106) :: cb 03 integer,dimension(26) :: ic 04 integer,dimension(1) :: icloc 05 character cntsign 06 integer :: i,j,m,k,k1,k2 07 read(*,*) m 08 read(*,'(100a1)')(ca(k),k=1,m) 09 ca(m+1) = ' ' 10 ic = 0 11 do i=1,m 12 k = iachar(ca(i))-iachar('a')+1 13 ic(k) = ic(k)+1 14 end do 15 icloc = minloc(ic) 16 cntsign = achar(icloc(1)+iachar('a')-1) 17 k1 = 1 18 k2 = 1 19 do i=1,m 20 if(ca(i)==ca(i+1)) then 21 k1 = k1+1 22 else 23 if(k1>3 .or. ca(i)==cntsign) then 24 do j=1,(k1+25)/26 25 cb(k2) = cntsign 26 if(k1>=26) then 27 cb(k2+1) = 'z' 28 k1 = k1-26 29 else 30 cb(k2+1) = achar(iachar('a')+k1-1) 31 end if 32 cb(k2+2) = ca(i) 33 k2 = k2+3 34 end do 35 else 36 cb(k2:k2+k1-1) = ca(i) 37 k2 = k2+k1 38 end if 39 k1 = 1 40 end if 41 end do 42 write(*,100) cntsign,k2-1 43 write(*,200) (cb(i),i=1,k2-1) 44 100 format(' control mark = ',a1,' data size =',i5) 45 200 format(' ',106a1) 46 end
設問 プログラムと実行結果を分析した記述中の に入れる正しい答えを,解答群の中から選べ。
(1) 次に示すデータを入力した場合,このプログラムの 30 行目の実行回数は 回である。
23 abbbbcccddaaaaeeeeeehhh
(2) (1) に示すデータを入力した場合,このプログラムの 19 行目から 41 行目の DO 構文の実行が終了したときの k2 の値は となる。
(3) このプログラムの 6 行目を,
integer :: i,m,k,k1,k2
に変更し,24 行目から 34 行目までを次のとおりに変更すれば,IF 構文を使わずにすむ。
do while (k1>0) cb(k2) = cntsign cb(k2+1) = achar(iachar('a')+ ) cb(k2+2) = ca(i) k1 = k1-26 k2 = k2+3 end do
(4) このプログラムの 19 行目を,誤って次のようにしたとき,(1) に示す入力データに 対する 43 行目の WRITE 文の出力結果は となる。
do i=1,m-1
a に関する解答群
ア 1 イ 2 ウ 3 エ 4
オ 5 カ 6 キ 7
b に関する解答群
ア 17 イ 18 ウ 19
エ 20 オ 21 カ 23
c に関する解答群
ア min(k1,26)-1 イ min(k1,26) ウ min(k1,26)+1
エ max(k1,26)-1 オ max(k1,26) カ max(k1,26)+1
d に関する解答群
ア afdbcccddfdaffe イ afdbcccddfdaffeh
ウ afdbcccddfdaffehh エ afdbcccddfdaffehhh
オ afdbfccddfdaffe カ afdbfccddfdaffeh
キ afdbfccddfdaffehh