IT
大學
已解決

この問題の答えが18になるはずなのですが、何故18になるのか分からないので教えて欲しいです。
途中でretの値が13になる所までは理解できるのですが、、
iを1からnまで1ずつ増やすとあるのでnを4まで増やした後にret+iを出力で、13+4して答えは17ではないのでしょうか。
今回nは4なのにnを5まで増やすのは何故ですか?

問8 1文法 [2]一次元配列 1107 次の記述中の に入れる正しい答えを、解答群の中から選べ。 ここで,配列の要 素番号は1から始まる。 107bne :8 (14 CT 15% dix) not 関数 array Calc を arrayCalc ({5, 3, 1, 2, 4}, 4) として呼び出すと, 戻り値は で ある。 :e hotbne :01 [プログラム] 1: ○整数型: arrayCalc (整数型の配列: data, 整数型: n) 2: 整数型: ret ← 0 hotbns :ST 3: 整数型: 4: if (n > data の要素数) 5:return -1 6: endif 9178 7: for (i を 1 から n まで 1 ずつ増やす) 8: ret ← ret + data [ data[i]] 9:endfor 0: return ret + i nal - - nel i nel hel H
基本情報技術者試験

解答

✨ 最佳解答 ✨

プログラム
1: 〇整数型: arrayCalc (整数型の配列: data, 整数型: n)
2:  整数型: ret ← 0
3:  整数型: i
4:  if ( n > dataの要素数 )
5:   retrun -1
6:  endif
7:  for ( i を 1から nまで 1ずつ増やす)
8:   ret ← ret + data[data[i]]
9:  endfor
10: return ret + i

arrayCalc({5,3,1,2,4}, 4) として上記プログラムを呼び出す。

---------

メインの処理である以下の動きを示します。
7:  for ( i を 1から nまで 1ずつ増やす)
8:   ret ← ret + data[data[i]]
9:  endfor
10: return ret + i

i=1 の時、data[1] = 5 なので data[data[i] = data[5] = 4 よって、ret ← 0 + 4 = 4
i=2 の時、data[2] = 3 なので data[data[i] = data[3] = 1 よって、ret ← 4 + 1 = 5
i=3 の時、data[3] = 1 なので data[data[i] = data[1] = 5 よって、ret ← 5 + 5 = 10
i=4 の時、data[4] = 2 なので data[data[i] = data[2] = 3 よって、ret ← 10 + 3 = 13

i は nまで forループで回るので i=4 でループを脱出しますが、このループ
処理として以下のような処理および判定がなされています。
i=1 の時、i≦4を満たすのでループ内の処理を実行。iを1増やす (つまりi=2となる)
i=2 の時、i≦4を満たすのでループ内の処理を実行。iを1増やす (つまりi=3となる)
i=3 の時、i≦4を満たすのでループ内の処理を実行。iを1増やす (つまりi=4となる)
i=4 の時、i≦4を満たすのでループ内の処理を実行。iを1増やす (つまりi=5となる)
i=5 の時、i≦4を満たさないのでループ脱出

10行目の return ret + i としては、retun 13 + 5 となるので戻り値は 18です。

lv0043

誤:i は nまで forループで回るので i=4 でループを脱出しますが、このループ
正:i は nまで forループで回るので i=4 までループ処理が実施されますが、このループ

lv0043

C (C++)や javaなど一般的なプログラミング言語の forはこのような動きであるものの、この問題の forがどのような振る舞いをする
のはわからないので説明で書いたような動作をするとは断言はできないと思います。
その場合は ももさん が言われるように、return ret + i で retrun 13 + 4 が実施される処理系がある可能性はあり、問題の
プログラミング言語仕様が提示されていない以上、18でなく17となることも否定できません。
なぜ18になるのか?という質問でしたので開設したような動作をする処理系であればこう処理されるのだろうという説明しましたが、
たとえば、for の実装が以下のようになる処理系であれば ももさん が言われるように、 return ret + i は17となるでしょう。

 i = 1
for-1:
 ret ← ret + data[data[i]]
 if ( i < n )
  i ← i + 1
  goto for-1
 endif

lv0043

補足:
答えが18となる場合の for の処理判定は以下のようで、最初ループの先頭で i が条件を満たすか調べて
満たす場合は処理実行。最後に iをカウントアップしてループの先頭に戻る。
満たさない場合はループ脱出。
という動作なので、 ループを脱出するときの i は 5です。

 i ← 1
for-1:
 if ( i <= n )
  ret ← ret + data[data[i]]
  i ← i + 1
  goto for-1
 endif

もも

詳しく解説していただきありがとうございます。
くるくると繰り返してループ脱出の条件としてi=5まで見るということでしょうか
類似問題を解いて慣れたいと思います
ありがとうございます!

lv0043

ループ脱出する条件は、i ← i + 1が実行された後で評価される、というわけです。

たとえば C や Java の for では以下のような記述をします。
for (i=1; i<=n; i++) {
ret = ret + data[data[i]]; // ret += data[data[i]];
}

C や javaのforは、言語仕様として以下のような動作仕様であると決められています
ので、 i ← i + 1が実行された後にループを脱出することになります。

1) i ← 1が実行される
2) i <= n が評価されて、 1 <= 4 を満たすのでループ内の処理を実行。
条件が満たさない場合はループ脱出。 6)へジャンプ
3) ret = ret + data[data[1]] が実行される
4) i ← i + 1が実行される
5) ループの先頭である 2)へジャンプ

上記の forを、forを使わないでコーディングした以下と同じ動作をします。

 i ← 1
for-1:
 if ( i <= n )
  ret ← ret + data[data[i]]
  i ← i + 1
  goto for-1
 endif

問題での for仕様が、forを使わないでコーディングした場合の以下に相当する
動作をするのであれば、i の値が 4でループを脱出しますので、問題の答えは 17
となります。

 i ← 1
for-1:
 ret ← ret + data[data[i]]
 if ( i < n )
i ← i + 1
  goto for-1
 endif

問題のプログラミング言語仕様がどのようであるのか?次第というわけです。

もも

ありがとうございます。
基本情報技術者試験の対策問題なので、問題の疑似プログラミング言語の仕様ということだと理解しました。

留言
您的問題解決了嗎?