✨ 最佳解答 ✨
プログラム
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です。
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
補足:
答えが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まで見るということでしょうか
類似問題を解いて慣れたいと思います
ありがとうございます!
ループ脱出する条件は、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
問題のプログラミング言語仕様がどのようであるのか?次第というわけです。
ありがとうございます。
基本情報技術者試験の対策問題なので、問題の疑似プログラミング言語の仕様ということだと理解しました。
誤:i は nまで forループで回るので i=4 でループを脱出しますが、このループ
正:i は nまで forループで回るので i=4 までループ処理が実施されますが、このループ