[更新日]1998.07.13
問13 次の Fortran プログラムの説明及びプログラムを読んで, 設問に答えよ。
〔プログラムの説明〕
児童の人数 n( 2 ≦ n ≦ 100)と n 人の児童の身長を入力して, 身長の高さで二つのグループに分け,全体と各グループの身長の平均を それぞれ計算し,その結果を出力するプログラムである。
(1) 児童を身長の低いグループ A と高いグループ B に分ける。
(2) 身長の低い方から m 番目までをグループ A とする。m の値は,
n が偶数の場合: m = n / 2
n が奇数の場合: m = (n+1) / 2
とする。
(3) グループに分けるには,身長が入力されている配列 x の m 番目の 要素 x(m) の値より小さい側も大きい側も完全に整列する必要はなく,
max{x(1),x(2),…,x(m−1)} ≦ x(m) ≦ min{x(m+1),x(m+2), …,x(n)}
となるように並べ替えればよい。並べ替えは次の手順で行う。
配列の先頭からの探索の開始位置を示す変数 ipl の初期値を 1 とし, 配列の最後からの探索の開始位置を示す変数 ipr の初期値を n とする。
配列 x の m 番目の要素 x(m) の値を v とする。
配列 x の ipl 番目から x(ipl),x(ipl+1),… の順に,値が v 以上 の要素を探し,見つかったらその番号を j とする。
配列 x の ipr 番目から x(ipr),x(ipr−1),… の順に,値が v 以下 の要素を探し,見つかったらその番号を k とする。
と で見つかった要素 x( j) と x(k) を入れ替える。
j の値に 1 を加え,k の値から 1 を引く。
j ≦ m かつ m ≦ k の間, 〜の処理を繰り返す。
j > m の場合は ipr に k を代入し,m > k の場合は ipl に j を代入する。
ipl < ipr の間,〜の処理を繰り返す。
この結果,
グループ A: x(1),x(2),…,x(m)
グループ B: x(m+1),x(m+2),…,x(n)
となる。
(4) 入力データ及び出力結果の例を図 1,図 2 に示す。
図1 入力データ例
図2 出力結果例
〔プログラム〕 (行番号) 01 integer :: n,m,i,j,k,ipl,ipr 02 real :: sum,suma,sumb,v,w 03 real ,dimension(100) :: x 04 read(*,100) n 05 read(*,110) (x(i),i=1,n) 06 if( n == (n / 2) * 2 ) then 07 m = n / 2 08 else 09 m = (n + 1) / 2 10 endif 11 ipl = 1 12 ipr = n 13 do while ( ipl < ipr ) 14 v = x(m) 15 j = ipl 16 k = ipr 17 do while ( j <= m .and. m <= k ) 18 do while ( x(j) < v ) 19 j = j + 1 20 end do 21 do while ( v < x(k) ) 22 k = k - 1 23 end do 24 w = x(j) 25 x(j) = x(k) 26 x(k) = w 27 j = j + 1 28 k = k - 1 29 end do 30 if( j > m ) ipr = k 31 if( m > k ) ipl = j 32 end do 33 suma = 0.0 34 sumb = 0.0 35 do i = 1,m 36 suma = suma + x(i) 37 end do 38 do i = m+1,n 39 sumb = sumb + x(i) 40 end do 41 sum = suma + sumb 42 write(*,200) sum/real(n),suma/real(m),sumb/real(n-m) 43 stop 44 100 format(i5) 45 110 format(10f7.2) 46 200 format(10x,'身長の平均'/& 47 & 15x,'全体 = ',f15.2 / 15x,'グループA = ',f15.2 /& 48 & 15x,'グループB = ',f15.2) 49 end
設問 次の記述中の に入れる正しい答えを,解答群の中から選べ。
(1) このプログラムの 6 行目から 10 行目までを変更すれば,IF 構文を 使わなくても同じ m の値を得るプログラムに書き換えられる。この変更として 適切なものは である。
(2) このプログラムの 35 行目から 40 行目までは,次のように変更すれば 二つの DO 構文を一つにまとめることができる。
do i =
suma = suma + x(i)
sumb = sumb + x(i+m)
end do
if( m - 1 == n / 2 ) then
suma = suma + x(m)
end if
(3) 図 1 の入力データ例において,このプログラムの 13 行目から 32 行目の DO 構文のループを 1 回だけ実行したとき,ipl と ipr の値は それぞれ となっている。
(4) このプログラムの 30 行目の条件が成立したとき, であることが保証される。
a に関する解答群
ア m = n / 2
イ m = n / 2 + 1
ウ m = (n + 1) / 2
エ m = (n + 1) / 2 + mod(n,2)
b に関する解答群
ア 1,m
イ 1,n
ウ 1,n+m
エ 1,n-m
c に関する解答群
ア ipl = 1 , ipr = 4
イ ipl = 1 , ipr = 9
ウ ipl = 2 , ipr = 4
エ ipl = 2 , ipr = 9
d に関する解答群
ア max{x(1),x(2),…,x(j)} ≦ min{x(k),x(k+1),…,x(n)}
イ max{x(1),x(2),…,x(m)} ≦ min{x(k),x(k+1),…,x(n)}
ウ max{x(1),x(2),…,x(j)} ≦ min{x(k+1),x(k+2),…,x(n)}
エ max{x(1),x(2),…,x(m)} ≦ min{x(k+1),x(k+2),…,x(n)}