プログラミング入門 6. forループ
この記事は、下記プログラミング入門資料の一部です。
for ループとは
forループとは、「N回繰り返し作業を行う」ということができるものです。
コードとしては以下のように書きます。
for (int i = 0; i < N; i++) { // ここに繰り返したい作業を書く }
ややこしいですね。
for文の構造は
for ( ➀ ; ② ; ③ ) { // ここに繰り返したい作業を書く }
において、以下のような実行内容や条件が含まれています。
- ➀ 最初の繰り返しが始まる前に実行される内容。
- 「int i = 0;」であれば「整数の入れ物iを作って、そこに0を入れる」となる。
- ② 各繰り返しの前に確認する条件。この条件を満たしていない時は繰り返しを終了する。
- 「i < N」であれば「iがNより小さい時」に実行されることになる。
- ③ 各繰り返しの後に実行される内容。
- 「i++」であれば「iに1を足す」が実行される。
- 「iに1を足す」という操作は「i = i + 1」と表現されるが、これは非常によく使われるので省略して「i++」と書くことができる。
- 同じように、「iから1を引く」という操作は「i = i - 1」と表現されるが、省略して「i--」と書くことができる。
つまり、
for (int i = 0; i < N; i++) { // ここに繰り返したい作業を書く }
の場合は
- ➀ 1番最初に、「整数の入れ物iを作って、そこに0を入れる」を実行する。
- ② 条件「i < N」が満たされているなら、{ }内の処理を実行する。条件が満たされていなければ、終了する。
- ③ { }内の処理が終わったら、「iに1を足す」を実行して、②に戻る。
という、繰り返しの処理を行うことが出来ます。
練習1
"Oyasumi"と10回表示してみましょう。
答え
for (int i = 0; i < 10; i++) { cout << "Oyasumi" << endl; }
練習2
"Ohayo"と5回表示してみましょう。
答え
for (int i = 0; i < 5; i++) { cout << "Ohayo" << endl; }
練習3
0から9までの10個の数字を順番に表示してみましょう。
答え
for (int i = 0; i < 10; i++) { cout << i << endl; }
iはどんどん増えていくので、毎回iの中身を表示するだけで上手くいきます。
練習問題の解説
N回分の点数データをfor文で受け取って、それが80以上かどうか毎回調べ、80未満なら足りない分の点数を足していけば良さそうです。
#include <iostream> using namespace std; int main(void){ // Here your code ! int N; cin >> N; // 必要な点数の合計点をanswerに記録することにします。 int answer = 0; // N 回繰り返すfor文です for (int i = 0; i < N; i++) { // i回目の点数をmに受け取ります。 int m; cin >> m; // mが80未満なら足りない分だけ、つまり(80 - m)だけ勉強しなければならないので、 // それをanswerに足しておきます if (m < 80) { answer = answer + (80 - m); } } cout << answer << endl; }
練習問題2の解説
小数点以下の切り上げにはceilというのを使います。これを使うために、先頭に
#include <cmath>
というのを追加しなければなりません。
追加後にコードの書き出しが
#include <cmath> #include <iostream> using namespace std; int main(void){
のようになっていればOKです。
ceilを使うと小数点以下を切り上げてくれます。たとえば、
int a = ceil( 1.5 );
とすると、aには2が入ります。
これで問題を解くのに必要な知識が揃いました。
N個のバグデータをforで受け取って、バグの合計数を記録しておく必要があります。
また、バグ0の製品はスルーするので、バグの含まれた製品の数も記録しておきましょう。
#include <cmath> #include <iostream> using namespace std; int main(void){ // Here your code ! int N; cin >> N; //バグを含んだ製品の数をbug_seihinに記録する。 int bug_seihin = 0; //バグの合計数をbugsに記録する。 int bugs = 0; // N個のバグデータを受け取るfor文 for (int i = 0; i < N; i++) { // バグの数を受け取る int A; cin >> A; // Aが0より大きい時だけを考えれば良い if( A > 0 ) { //バグを含んだ製品の数が1増える bug_seihin++; //バグの合計数も加算する bugs = bugs + A; } } // 小数の入れ物heikinを作って、そこに平均バグ数を入れておく double heikin = (double) bugs / bug_seihin; // heikinの小数点以下を切り上げた数が答えになる int answer = ceil( heikin ); cout << answer << endl; }
余談
double heikin = bugs / bug_seihin;
と
double heikin = (double) bugs / bug_seihin;
で結果が変わります。
上の場合は bugs / bug_seihin を「整数として計算してから小数に変換して」heikinに入れています。「整数として計算してから」というのは「小数点以下を切り捨てて整数に直してから」ということになるので、正しくない値が入ることがあります。
下の場合は「小数として計算して」heikinに入れています。この方法なら望んだ結果が得られます。
クソ面倒ですね。
練習問題3の解説
E[0]〜E[5]とL[0]〜L[5]を見比べる時に、
for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { if (E[i] == L[j]) { atari++; } } }
というように2重でforループを使えば、E[0]とL[0]、E[0]とL[1]、E[0]とL[2]、 …… 、E[5]とL[4]、E[5]とL[5]、を見比べることができる。
#include <cmath> #include <iostream> using namespace std; int main(void){ // Here your code ! //当選番号の6つの数字を記録しておく int E[6]; for (int i = 0; i < 6; i++) { cin >> E[i]; } // ボーナス数字を記録しておく int B; cin >> B; // 自分の数字を記録しておく int L[6]; for (int i = 0; i < 6; i++) { cin >> L[i]; } // 当選番号と一致した数をatariに記録する int atari = 0; // 当選番号のi番目と自分の数字のj番目を見比べて、同じならatariに1を足す for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { if (E[i] == L[j]) { atari++; } } } // answerに当選順位を記録する int answer; // 6つ当たっていれば1等 if (atari == 6) { answer = 1; } else if (atari == 5) { // 5つ当たっていれば3等 answer = 3; //ただし、ボーナス数字が入っていれば2等になるので、 //ボーナス数字と自分の数字を見比べる for (int i = 0; i < 6; i++) { if (L[i] == B) { answer = 2; } } } else if (atari == 4) { //4つ当たっていれば4等 answer = 4; } else if (atari == 3) { //3つ当たっていれば5等 answer = 5; } else { //それ以外ははずれなので0 answer = 0; } cout << answer << endl; }
練習問題4の解説
for文で歩数データを受け取り、どんどん足していき、その合計がK以上になった時を出力すれば良さそうです。
合計がK以上になった後の歩数データは要らないので、そこでfor文を強制終了します。
for文を強制終了するときはfor文内でbreakをすると良いです。
breakの例
iがAよりも大きくなったら終了するfor文です。
for (int i = 0; i < N; i++) { if ( i > A ) { break; } }
解答例は以下の通り。
#include <iostream> using namespace std; int main(void){ int N; int K; cin >> N; cin >> K; // finishに目標達成日を記録する int finish; // i日目までの合計歩行数を記録する int sum = 0; for (int i = 0; i < N; i++) { // i日目の歩数データを受けとる int a; cin >> a; sum = sum + a; // i日目までの合計がK以上になったら、finishにその日付を記録して終了する if ( sum >= K ) { finish = i; // for文を強制終了できる break; } } // finishに記録されている日付は0日目から数えてi日目なので、1起点にする finish = finish + 1; //出力 cout << finish << endl; }
練習問題5の解説
min(a, b);
とすると、aとbの小さい方が得られます。
これを利用して、上手く最小の時間を出してみましょう。
#include <iostream> using namespace std; int main(void){ int N; cin >> N; // dekitateに一番出来たてのたこ焼きが何秒前に出来たかを入れます。 // 最初はとりあえず最大値である100をいれます。 int dekitate = 100; for (int i = 0; i < N; i++) { // i番目のたこ焼きが焼けた時間をTに受けとります int T; cin >> T; // dekitateとTの小さい方をdekitateに入れておきます dekitate = min(dekitate, T); } cout << dekitate << endl; }